]> git.mdlowis.com Git - proto/sclpl-rb.git/commitdiff
implemented first pass at pratt parser
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 31 Jul 2019 03:19:18 +0000 (23:19 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 31 Jul 2019 03:19:18 +0000 (23:19 -0400)
compile.rb
example.src

index 99ff7ef6caef294210160a9b3b9ca466dbc6e248..399c6f3de0c6b8400cf9c96c31caa6bf2b971158 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env ruby
 
 require 'strscan'
+require 'pp'
 
 module Type
   Void = "void"
@@ -157,9 +158,13 @@ class Parser
     unary:    8,
     call:     9,
     primary: 10,
+    eof: 11
   }
 
-  RULES = {}
+  RULES = {
+    "("  => { prefix: :grouping, infix: :func_call, level: :call },
+    :int => { prefix: :constant, infix: nil,        level: :none },
+  }
 
   def initialize(path)
     @lex = Lexer.new(path)
@@ -208,7 +213,7 @@ class Parser
       expect("=")
       value = expression()
     end
-    pp value
+    p "value", value
   end
 
   def declaration(syms)
@@ -252,28 +257,45 @@ class Parser
     RULES[tok.type]
   end
 
+  def keepGoing(level)
+    rule = getRule(peek())
+    (LEVELS[level] <= LEVELS[rule[:level]]) if rule
+  end
+
   def parseLevel(level)
-#    advance()
-#    prefixRule = getRule(@prev)[:prefix]
-#    if not prefixRule then
-#      error("expected an expression")
-#    end
-#    send(prefixRule)
-#    while (level <= LEVELS[getRule(@curr)[:level]])
-#      advance()
-#      infixRule = getRule(@prev)[:infix]
-#      send(infixRule)
-#    end
+    consume()
+    prefixRule = getRule(@prev)[:prefix]
+    if not prefixRule then
+      error("expected an expression")
+    end
+    ast = send(prefixRule)
+    while keepGoing(level)
+      consume()
+      infixRule = getRule(@prev)[:infix]
+      ast = send(infixRule, ast)
+    end
+    ast
   end
 
   def constant()
-    if (peek().type == :int)
-      AST::Value.new(Type::Int, consume().text.to_i)
+    if (@prev.type == :int)
+      AST::Value.new(Type::Int, @prev.text.to_i)
     else
       error("not a valid constant")
     end
   end
 
+  def grouping()
+    ast = expression()
+    expect(")")
+    ast
+  end
+
+  def func_call(ast)
+    expect(")")
+    ast
+  end
+
   def error(str)
     raise str
   end
index c5b48c177e210ababab867c05929198d9476d18c..dd68e444b48d19259048b45d20b2779448c54b8c 100644 (file)
@@ -4,8 +4,8 @@ provides {
   fun main(args string[]) int
 }
 
-let foo int = 42
+let foo int = (42)
 
 fun main(args string[]) int {
-  42
+  42()
 }