From 6d90a96ffd1c1cc59170b6bcf1eebb3570447eac Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 10 Feb 2020 15:14:55 -0500 Subject: [PATCH] started working on code generation and type checking as a single pass --- compile.rb | 46 ++++++++++++++++++++++++++++++++++++---------- lib/main.m | 2 ++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/compile.rb b/compile.rb index 5c609d7..d6c2578 100755 --- a/compile.rb +++ b/compile.rb @@ -61,8 +61,9 @@ BuiltinSyms = { Modules = {} class Symtable - def initialize + def initialize() @builtins = BuiltinSyms + @modules = Modules @scopes = [{}] end @@ -81,6 +82,17 @@ class Symtable def scope_stop @scopes.pop() end + + def canonical_type(type) + return name if not type.is_a? String + while type.is_a? String + newtype = self[type] + raise "unknown type #{type}" if newtype.nil? + raise "#{type} is not a type (kind: #{type[:kind]})" if (type[:kind] != :type) + type = newtype + end + type + end end class Lexer @@ -226,10 +238,11 @@ class Parser else error("invalid symbol definition") end - if api_only && sym[:export] then + if api_only then sym[:value] = nil + sym = nil if not sym[:export] end - @symbols[sym[:name]] = sym + @symbols[sym[:name]] = sym if sym end @symbols end @@ -420,7 +433,6 @@ class Parser while keepGoing(level) consume() infixRule = getRule(@prev)[:infix] -# break if infixRule.nil? # Is this needed? ast = send(infixRule, ast) end ast @@ -580,19 +592,23 @@ class Package @declares = {} @definitions = {} add_file(path, api_only) - type_check end def add_file(path, api_only = false) parse = Parser.new(path) @name = parse.module() @imports = parse.imports() + @definitions = {} @imports.each do |m| next if Modules[m] - pkg = Package.new("lib/#{m.downcase}.m", api_only = true) + pkg = Package.new("lib/#{m.downcase}.m", true) Modules[pkg.name] = pkg.definitions() + @definitions[pkg.name] = { + kind: :module, + type: :module + } end - @definitions = parse.definitions(api_only) + @definitions.merge!(parse.definitions(api_only)) end def dump @@ -603,10 +619,20 @@ class Package }) end - def type_check + def generate() end end +############################## +# Code Generation +############################## + pkg = Package.new("lib/main.m") -#pp Modules -#pkg.dump() +syms = Symtable.new() +pkg.definitions.each do |name, val| + next if val[:kind] == :module +# pp val + type = syms.canonical_type(val[:type]) + puts name + " ->" + pp type +end diff --git a/lib/main.m b/lib/main.m index 161f91a..eddc270 100644 --- a/lib/main.m +++ b/lib/main.m @@ -1,6 +1,8 @@ module Main imports (X11, XSel, Posix) +Foo is Int + cmd : ?[String] = { foo = 123, bar = 321 -- 2.52.0