]> git.mdlowis.com Git - proto/sclpl-rb.git/commitdiff
started working on code generation and type checking as a single pass
authorMichael D. Lowis <mike.lowis@gentex.com>
Mon, 10 Feb 2020 20:14:55 +0000 (15:14 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Mon, 10 Feb 2020 20:14:55 +0000 (15:14 -0500)
compile.rb
lib/main.m

index 5c609d7c284d241709a97c26fd0d815ca3fa60db..d6c257840309d80e324d1c9df754410ac8a57bfa 100755 (executable)
@@ -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
index 161f91a74cc63f4275111bcf0b197964d75e5cf8..eddc270ffd9e62f4f69abfce1fdac16568a1bd00 100644 (file)
@@ -1,6 +1,8 @@
 module Main
 imports (X11, XSel, Posix)
 
+Foo is Int
+
 cmd : ?[String] = {
     foo = 123,
     bar = 321