]> git.mdlowis.com Git - proto/aas.git/commitdiff
added multiplication, division, and AND
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 13 Nov 2023 03:30:16 +0000 (22:30 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 13 Nov 2023 03:30:16 +0000 (22:30 -0500)
aas.rb
cerise.m
cerise.rb

diff --git a/aas.rb b/aas.rb
index 6664e67e8645c8b07e86f9ac781dd60a1898e359..672cff8d06f52bbfcdd211d1d2d07063820dcbaa 100755 (executable)
--- a/aas.rb
+++ b/aas.rb
@@ -69,21 +69,21 @@ module Targets
       def muli
         emit "popq      %rax"
         emit "popq      %rbx"
-        emit "imull     %rbx, %rax"
+        emit "imulq     %rbx, %rax"
         emit "pushq     %rax"
       end
 
       def divi
         emit "popq      %rax"
         emit "popq      %rbx"
-        emit "idivl     %rbx, %rax"
+        emit "idivq     %rbx, %rax"
         emit "pushq     %rax"
       end
 
       def modi
         emit "popq      %rax"
         emit "popq      %rbx"
-        emit "idivl     %rbx, %rax"
+        emit "idivq     %rbx, %rax"
         emit "pushq     %rdx"
       end
 
index 81920d1b28b547791c960915487a82e9deab1c81..fc7e1bb1bffa13bce98f296af7855ec6e7b179c4 100644 (file)
--- a/cerise.m
+++ b/cerise.m
@@ -1,4 +1,4 @@
 main()
 {
-    return 42
+    return 43 % 2
 }
index 35bb776d867e3b99d264ce294485d5d660c5be68..6daa8e5957ec003fa368020dc6c4e960f3144721 100755 (executable)
--- a/cerise.rb
+++ b/cerise.rb
@@ -28,7 +28,7 @@ class Lexer
   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 = /"(\\"|[^"])*"/
@@ -192,8 +192,9 @@ module IR
   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)
@@ -689,6 +690,54 @@ class Parser
   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
 
@@ -708,179 +757,6 @@ class Parser
       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
@@ -889,8 +765,10 @@ 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
 
@@ -904,6 +782,21 @@ module Codegen
       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")