SPACE = /([ \t\v\n\r]+|#.*\n)/
IDENT = /[_a-zA-Z][_a-zA-Z0-9]*!?/
BRACES = /[\(\)\[\]\{\}\.]/
- OPERATORS = /[:,<>*\/=+\-\$?!]+/
+ OPERATORS = /[:,<>*\/=+\-\$?!%]+/
INTEGER = /[0-9]+/
FLOATING = /[0-9]+\.[0-9]+/
STRING = /"(\\"|[^"])*"/
Return = Struct.new(:loc, :type, :value)
Const = Struct.new(:loc, :type, :value)
Var = Struct.new(:loc, :type, :name)
-
Def = Struct.new(:loc, :type, :name, :value)
+ Op = Struct.new(:loc, :type, :op, :left, :right)
+
# EnvRef = Struct.new(:loc, :type, :index)
# Let = Struct.new(:loc, :type, :var, :expr, :body)
end
def expression()
+ simple_expr()
+ end
+
+ def simple_expr()
+ term()
+
+# 269 /* first term and +/- unary ops */
+# 270 if (matches_oneof(p, (int[]){'+', '-', 0}))
+# 271 {
+# 272 int op = consume(p);
+# 273 SsaNode* operand = term(p);
+# 274 check_num(p, operand);
+# 275 expr = ssa_op(p, op, operand, NULL);
+# 276 }
+# 277 else
+# 278 {
+# 279 expr = term(p);
+# 280 }
+# 281
+# 282 /* optional second term and binary ops */
+# 283 while (matches_oneof(p, (int[]){'+', '-', OR, 0}))
+# 284 {
+# 285 int op = consume(p);
+# 286 SsaNode* right = term(p);
+# 287 if (op == OR)
+# 288 {
+# 289 check_bools(p, expr, right);
+# 290 }
+# 291 else
+# 292 {
+# 293 check_nums(p, expr, right);
+# 294 }
+# 295 expr = ssa_op(p, op, expr, right);
+# 296 }
+
+ end
+
+ def term()
+ left = factor()
+ while matches_any(["*", "/", "%", :and])
+ op = consume()
+ right = factor();
+ left = IR::Op.new(location, nil, op.text, left, right)
+ end
+ left
+ end
+
+ def factor()
constant()
end
error("invalid constant")
end
end
-
-
-
-# def declaration()
-# if matches(:ident)
-# expr = ident()
-# expr.type = syms[expr.name][:type] if syms[expr.name]
-# if accept("=")
-# value = expression()
-# syms.add_sym(expr.name, expr.loc, :var, expr.type)
-# IR::Let.new(expr.loc, nil, expr, value, nil)
-# elsif accept(":")
-# expr.type = type_spec()
-# syms.add_sym(expr.name, expr.loc, :var, expr.type)
-# nil
-# else
-# expression()
-# end
-# else
-# expression()
-# end
-# end
-#
-# def expression()
-# if matches(:let)
-# let_expr()
-# else
-# complex_expr()
-# end
-# end
-#
-# def complex_expr()
-# expr = nil
-# if matches(:if)
-# expr = if_expr()
-# elsif matches(:set)
-# expr = var_set()
-# elsif matches_any(["+","-", "!"])
-# expr = unop_call()
-# else
-# expr = atomic_expr()
-# if matches("(")
-# expr = func_call(expr)
-# elsif operator?
-# expr = binop_call(expr)
-# end
-# end
-# expr
-# end
-#
-# def atomic_expr()
-# if matches(:func)
-# func_expr()
-# elsif matches(:ident)
-# ident()
-# else
-# constant()
-# end
-# end
-#
-#
-#
-#
-# def application()
-## expr = atomic_expr()
-## expr = func_call(expr) if matches("(")
-# # EQ, NEQ, '<', LTEQ, '>', GTEQ
-# end
-#
-# def simple_expr()
-# # '+', '-', OR
-# end
-#
-# def term()
-# # '*', '/', '%', AND
-# end
-#
-# def factor()
-# # '(', NOT, atomic
-# end
-#
-#
-#
-#
-# def unop_call()
-# op = consume()
-# rhs = atomic_expr()
-# IR::Apply.new(op.pos, nil, op.type, [rhs])
-# end
-#
-# def binop_call(expr)
-# op = consume()
-# rhs = atomic_expr()
-# IR::Apply.new(expr.loc, nil, op.type, [expr, rhs])
-# end
-#
-# def if_expr()
-# loc = expect(:if).pos
-# cond = atomic_expr()
-# expect(:then)
-# branch1 = expression()
-# expect(:else)
-# branch2 = expression()
-# IR::If.new(loc, nil, cond, branch1, branch2)
-# end
-#
-# def var_set()
-# loc = expect(:set).pos
-# name = ident()
-# expect("=")
-# expr = expression()
-# IR::Set.new(loc, nil, name, expr)
-# end
-#
-# def func_call(func)
-# args = []
-# expect("(")
-# while !matches(")")
-# args << atomic_expr()
-# expect(",") if not matches(")")
-# end
-# expect(")")
-# IR::Apply.new(func.loc, nil, func, args)
-# end
-#
-# def func_expr()
-# loc = expect(:func).pos
-# args = []
-# expect("(")
-# while !matches(")")
-# args << ident()
-# args.last.type = type_spec() if accept(":")
-# expect(",") if not matches(")")
-# end
-# expect(")")
-# type = type_spec() if accept(":")
-# body = expression()
-# IR::Func.new(loc, type, args, body)
-# end
-#
-# def ident()
-# name = expect(:ident)
-# IR::Var.new(name.pos, nil, name.text.to_sym)
-# end
-#
-# def typename()
-# name = expect(:ident)
-# sym = syms[name.text]
-# if sym && sym[:kind] != :type
-# error(name.pos, "#{name.text} is not a valid type")
-# end
-# IR::Var.new(name.pos, nil, name.text.to_sym)
-# end
-#
-#
-# def let_expr()
-# expect(:let)
-# name = ident()
-# name.type = type_spec() if accept(":")
-# expect("=")
-# expr = complex_expr()
-# expect(:in)
-# body = expression()
-# IR::Let.new(name.loc, nil, name, expr, body)
-# end
-#
-# def type_spec()
-# type = [typename().name]
-# while accept("->")
-# type << typename().name
-# end
-# (type.length == 1 ? type[0] : type)
-# end
end
module Codegen
emit_return(v)
elsif v.is_a? IR::Const then
emit_const(v)
-# else
-# emit_const(v)
+ elsif v.is_a? IR::Op then
+ emit_op(v)
+ else
+ raise "not implemented"
end
end
puts " int #{v.value}"
end
end
+
+ def self.emit_op(v)
+ emit(v.right) if v.right
+ emit(v.left)
+ case v.op
+ when "*"
+ puts " muli"
+ when "/"
+ puts " divi"
+ when "%"
+ puts " modi"
+ else
+ raise "not implemented"
+ end
+ end
end
$parser = Parser.new("cerise.m")