]> git.mdlowis.com Git - proto/sclpl-rb.git/commitdiff
added member access and function calls
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 29 Jan 2020 04:06:16 +0000 (23:06 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 29 Jan 2020 04:06:16 +0000 (23:06 -0500)
compile.rb
example.src

index 9f3fdba44e2ac951b48c74fd6139b7a934792455..2cbbd44adec928e8bf087e2214cb0fe4ee0446c6 100755 (executable)
@@ -20,6 +20,7 @@ module Ast
   Return = Struct.new(:type, :val)
   Var = Struct.new(:name, :type, :value)
   IfStmt = Struct.new(:cond, :br1, :br2)
+  Ident = Struct.new(:name)
 end
 
 BuiltinSyms = {
@@ -57,7 +58,7 @@ class Lexer
   Tok = Struct.new(:text, :file, :pos, :type)
   SPACE = /([ \t\v\n\r]+|#.*\n)/
   IDENT = /[_a-zA-Z][_a-zA-Z0-9]*/
-  BRACES = /[\(\)\[\]\{\}]/
+  BRACES = /[\(\)\[\]\{\}\.]/
   OPERATORS = /[*\/=+-:\$]/
   INTEGER = /[0-9]+/
   STRING = /"(\\"|[^"])*"/
@@ -124,11 +125,13 @@ class Parser
   LVLNAMES = LEVELS.keys
 
   RULES = {
+    "."     => { prefix: nil,       infix: :access,    level: :call   },
     "("     => { prefix: :grouping, infix: :func_call, level: :call   },
     "+"     => { prefix: :unary,    infix: :binary,    level: :term   },
     "-"     => { prefix: :unary,    infix: :binary,    level: :term   },
     "*"     => { prefix: nil,       infix: :binary,    level: :factor },
     "/"     => { prefix: nil,       infix: :binary,    level: :factor },
+    :ident  => { prefix: :variable, infix: nil,        level: :none   },
     :nil    => { prefix: :constant, infix: nil,        level: :none   },
     :bool   => { prefix: :constant, infix: nil,        level: :none   },
     :int    => { prefix: :constant, infix: nil,        level: :none   },
@@ -292,13 +295,13 @@ class Parser
       return_statement()
     elsif matches(:if)
       if_statement()
-    elsif matches(:ident)
-      ident = expect(:ident)
-      if matches(":")
-        declaration(ident)
-      else
-        binary(ident)
-      end
+#    elsif matches(:ident)
+#      ident = expect(:ident)
+#      if matches(":")
+#        declaration(ident)
+#      else
+#        binary(ident)
+#      end
     else
       expression()
     end
@@ -363,13 +366,27 @@ class Parser
     ast
   end
 
+  def access(left)
+    right = Ast::Ident.new(expect(:ident).text)
+    access = Ast::Apply.new(nil, ".", [left, right])
+    if accept("(")
+      func_call(access)
+    else
+      access
+    end
+  end
+
+  def variable()
+    Ast::Ident.new(@prev.text)
+  end
+
   def constant()
     if (@prev.type == :int || @prev.type == :byte)
       val = @prev.text.to_i
       if @prev.type == :byte
         error("invalid byte value") if (val < 0 || val > 255)
       end
-      Ast::Val.new(Type::Int, )
+      Ast::Val.new(Type::Int, nil)
     elsif (@prev.type == :string)
       Ast::Val.new("String", @prev.text)
     elsif (@prev.type == :nil)
@@ -392,8 +409,13 @@ class Parser
   end
 
   def func_call(ast)
+    call = Ast::Apply.new(nil, ast, [])
+    while !matches(")")
+      call[:args] << expression()
+      expect(",") if !matches(")")
+    end
     expect(")")
-    Ast::Apply.new(nil, ast, [])
+    call
   end
 
   def unary()
@@ -404,6 +426,7 @@ class Parser
   def nextLevel(tok)
     level = getRule(@prev)[:level]
     index = LVLNAMES.find_index(level)
+    error("unknown operator type '#{tok}'") if not index
     LVLNAMES[index + 1]
   end
 
index bed21b6c94490861b1a886754fc7f89499601cef..a0024b49747f4d9c3f60dc1752a79a84cc070ded 100644 (file)
@@ -1,28 +1,26 @@
 module Main
 imports (X11, XSel, Posix)
 
-cmd : [String] = true
-
-#[ "fetch", nil, nil ]
+#cmd : [String] = true
 
 fetchsel(sel : String)
 {
-    foo : String = 123
-    1 + 1
-    return 0
-    if 1 { return 5 } else {}
-    if 1 {} else if 1 {}
+#    foo : String = 123
+#    1 + 1
+#    return 0
+#    if 1 { return 5 } else {}
+#    if 1 {} else if 1 {}
+#    cmd[1] = sel;
+    Posix.exec(cmd)
+}
 
-##    cmd[1] = sel;
-##    Posix.exec(cmd)
+main(args : [String]) : Int
+{
+#    x : X11.Config = 0
+#    X11.init(x)
+#    X11.mkwin(x, 1, 1, X11.PropertyChangeMask)
+#    XSel.init(x)
+#    X11.loop(x, nil)
+#    return 0
 }
-#
-#$main(args : array of String) : Int
-#{
-##    x : X11.Config = {}
-##    X11.init(&x)
-##    X11.mkwin(&x, 1, 1, X11.PropertyChangeMask)
-##    XSel.init(&x)
-##    X11.loop(&x, nil)
-#}
-#
+