]> git.mdlowis.com Git - proto/sclpl-rb.git/commitdiff
added declaration parsing and scaffolding for array
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 31 Jan 2020 03:20:40 +0000 (22:20 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 31 Jan 2020 03:20:40 +0000 (22:20 -0500)
compile.rb
example.src

index dc048bb988b03b0a404138d1f19a932eb16ede8a..1dec61fbed68700a5ce5014652070d970a35701c 100755 (executable)
@@ -75,9 +75,13 @@ class Lexer
     "else" => :else,
   }
 
+  attr_accessor :file
+  attr_accessor :data
+
   def initialize(path)
     @file = path
-    @data = StringScanner.new(File.read(path))
+    @text = File.read(path)
+    @data = StringScanner.new(@text)
   end
 
   def get_id_type(str)
@@ -105,6 +109,10 @@ class Lexer
       Tok.new("EOF", @file, @data.pos, :eof)
     end
   end
+
+  def linenum(tok = nil)
+    @text[0..(tok.pos || @data.pos)].count("\n") + 1
+  end
 end
 
 class Parser
@@ -127,6 +135,7 @@ class Parser
 
   RULES = {
     "."     => { prefix: nil,       infix: :access,    level: :call   },
+    "["     => { prefix: nil,       infix: :subscript, level: :call   },
     "("     => { prefix: :grouping, infix: :func_call, level: :call   },
     "+"     => { prefix: :unary,    infix: :binary,    level: :term   },
     "-"     => { prefix: :unary,    infix: :binary,    level: :term   },
@@ -303,13 +312,8 @@ 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)
+      decl_or_expr()
     else
       expression()
     end
@@ -345,6 +349,15 @@ class Parser
     var
   end
 
+  def decl_or_expr()
+    ident = Ast::Ident.new(expect(:ident).text)
+    if matches(":")
+      declaration(@prev)
+    else
+      parseNextLevel(ident, :none)
+    end
+  end
+
   #######################################
   # Expression Parsing
   #######################################
@@ -365,7 +378,11 @@ class Parser
     consume()
     prefixRule = getRule(@prev)[:prefix]
     error("error parsing expression") if not prefixRule
-    ast = send(prefixRule)
+    parseNextLevel(send(prefixRule), level)
+  end
+
+  def parseNextLevel(left, level)
+    ast = left
     while keepGoing(level)
       consume()
       infixRule = getRule(@prev)[:infix]
@@ -384,6 +401,18 @@ class Parser
     end
   end
 
+  def subscript(left)
+    right = expression()
+#    p right
+    ast = Ast::Apply.new(nil, "[", [left, right])
+#    p ast
+    expect("]")
+    p peek()
+    ast = parseNextLevel(ast, :call)
+#    p ast
+    ast
+  end
+
   def variable()
     Ast::Ident.new(@prev.text)
   end
@@ -449,7 +478,7 @@ class Parser
   # Parsing Primitives
   #######################################
   def error(str)
-    puts str
+    puts "#{@lex.file}:#{@lex.linenum(@next || @prev)}: #{str}"
     exit 1
   end
 
index f8a72d177d2fa777bb04d0cee6094e905ff51020..9aa2bd48f492f432d9ccf314ec47d3a7b2dcb663 100644 (file)
@@ -6,21 +6,21 @@ cmd : ?[String] = true
 fetchsel(sel : String)
 {
 #    foo : String = 123
-#    1 + 1
-#    return 0
 #    if 1 { return 5 } else {}
 #    if 1 {} else if 1 {}
-#    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)
+    cmd[1] = sel
+#    1 + 1
+#    Posix.exec(cmd)
 #    return 0
 }
 
+#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
+#}
+