From 34bc2da3b097db0259f48b07ce5879d34006822a Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Sat, 1 Feb 2020 14:32:37 -0500 Subject: [PATCH] fixed up array and assignment parsing --- compile.rb | 38 ++++++++++++++++++++------------------ example.src | 32 ++++++++++++++++---------------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/compile.rb b/compile.rb index 1dec61f..a6eb88c 100755 --- a/compile.rb +++ b/compile.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'strscan' -require 'pp' module Type Nil = Struct.new(:value) @@ -15,13 +14,13 @@ module Type end module Ast - Nil = Struct.new(:value) + Nil = Struct.new(:type, :value) Val = Struct.new(:type, :value) Apply = Struct.new(:type, :func, :args) Return = Struct.new(:type, :val) - Var = Struct.new(:name, :type, :value) + Var = Struct.new(:type, :name, :value) IfStmt = Struct.new(:cond, :br1, :br2) - Ident = Struct.new(:name) + Ident = Struct.new(:type, :name) end BuiltinSyms = { @@ -141,6 +140,7 @@ class Parser "-" => { prefix: :unary, infix: :binary, level: :term }, "*" => { prefix: nil, infix: :binary, level: :factor }, "/" => { prefix: nil, infix: :binary, level: :factor }, + "=" => { prefix: nil, infix: :assign, level: :assign }, :ident => { prefix: :variable, infix: nil, level: :none }, :nil => { prefix: :constant, infix: nil, level: :none }, :bool => { prefix: :constant, infix: nil, level: :none }, @@ -219,11 +219,12 @@ class Parser pointer_type() elsif matches("?") nilable_type() -# elsif matches(:func) -# func_type() else name = expect(:ident).text - # TODO: check the type exists + name = [name] if matches(".") + while accept(".") + name << expect(:ident) + end name end end @@ -341,7 +342,7 @@ class Parser end def declaration(name) - var = Ast::Var.new(name.text, nil, nil) + var = Ast::Var.new(nil, name.text, nil) expect(":") var.type = type_specifier() expect("=") @@ -350,11 +351,11 @@ class Parser end def decl_or_expr() - ident = Ast::Ident.new(expect(:ident).text) + ident = Ast::Ident.new(nil, expect(:ident).text) if matches(":") declaration(@prev) else - parseNextLevel(ident, :none) + parseLevel(:assign, false) end end @@ -374,8 +375,8 @@ class Parser (LEVELS[level] <= LEVELS[rule[:level]]) if rule.keys.length > 0 end - def parseLevel(level) - consume() + def parseLevel(level, take = true) + consume() if take prefixRule = getRule(@prev)[:prefix] error("error parsing expression") if not prefixRule parseNextLevel(send(prefixRule), level) @@ -386,13 +387,14 @@ class Parser while keepGoing(level) consume() infixRule = getRule(@prev)[:infix] +# break if infixRule.nil? # Is this needed? ast = send(infixRule, ast) end ast end def access(left) - right = Ast::Ident.new(expect(:ident).text) + right = Ast::Ident.new(nil, expect(:ident).text) access = Ast::Apply.new(nil, ".", [left, right]) if accept("(") func_call(access) @@ -403,18 +405,18 @@ class Parser 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 assign(left) + Ast::Apply.new(left.type, "=", [left, expression()]) + end + def variable() - Ast::Ident.new(@prev.text) + Ast::Ident.new(nil, @prev.text) end def constant() diff --git a/example.src b/example.src index 9aa2bd4..b1de7e7 100644 --- a/example.src +++ b/example.src @@ -5,22 +5,22 @@ cmd : ?[String] = true fetchsel(sel : String) { -# foo : String = 123 -# if 1 { return 5 } else {} -# if 1 {} else if 1 {} - cmd[1] = sel -# 1 + 1 -# Posix.exec(cmd) -# return 0 + foo : String = 123 + foo = 3 + Posix.exec(cmd) + if 1 { return 5 } else {} + if 1 {} else if 1 {} + cmd[1] = 1 + 2 * 5 + 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 -#} +$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 +} -- 2.54.0