module TestSuite
-
TestLiterals()
{
assert 42
}
TestLtOps(){
+ assert (1 < 2) == true
+ assert (1.0 < 2.0) == true
+ assert (2 < 1) == false
+ assert (2.0 < 1.0) == false
}
TestLtEqOps(){
+ assert (1 <= 2) == true
+ assert (2 <= 2) == true
+ assert (1.0 <= 2.0) == true
+ assert (2.0 <= 2.0) == true
+ assert (2 <= 1) == false
+ assert (2.0 <= 1.0) == false
}
TestGtOps(){
+ assert (1 > 2) == false
+ assert (1.0 > 2.0) == false
+ assert (2 > 1) == true
+ assert (2.0 > 1.0) == true
}
TestGtEqOps(){
+ assert (1 >= 2) == false
+ assert (1.0 >= 2.0) == false
+ assert (2 >= 1) == true
+ assert (1 >= 1) == true
+ assert (2.0 >= 1.0) == true
+ assert (1.0 >= 1.0) == true
}
TestIfBlocks(){
} else {
assert true
}
+ if (2 < 1) {
+ assert false
+ } else {
+ assert true
+ }
}
Main()
TestArrayOps()
TestHashOps()
TestEqOps()
+ TestLtOps()
+ TestLtEqOps()
+ TestGtOps()
+ TestGtEqOps()
TestNeqOps()
TestIfBlocks()
}
# TODO:
#
+# * Fix type designation in symbol table
+# * Add Import/Export statements
+# * Add constant definitions
+# * Add type definitions
+#
# * Add unary operators for integers
# * Add type checking to operators on constants
# * Add optimization of constant operators
# * Add increment/decrement optimization
-# * Implement function calls
-# * Implement string constants
-# * Implement if statement
# * Implement tail call optimization?
require 'stringio'
@path = path
@syms = SymTable.new
@checker = TypeChecker.new(self)
+
+ syms.add_builtin(:Length, :func, [:any, :int], nil)
+
+
# syms.add_builtin(:void, 0, :type, :void)
# syms.add_builtin(:bool, 0, :type, :bool)
# syms.add_builtin(:int, 0, :type, :int)
# syms.add_builtin(:string, 0, :type, :string)
# syms.add_builtin(:float, 0, :type, :float)
- syms.add_builtin(:Length, :func, [:any, :int], nil)
- syms.add_builtin(:Error, :func, [:any, :void], nil)
+# syms.add_builtin(:Error, :func, [:any, :void], nil)
parse_file(path)
end
+ def symbols()
+ @syms.globals.map do |k,v|
+ [k, {kind: v.kind, type: v.type}]
+ end.to_h
+ end
+
def linenum(pos)
@lex.linenum(pos)
end
def each(&block)
@scopes.last.each(&block)
end
+
+ def globals
+ @scopes[1]
+ end
end
# Parse and Analyze
##
-$parser = Parser.new("cerise-c.m")
-$checker = TypeChecker.new($parser)
-$codegen = Codegen.new($parser)
-$codegen.output("cerise-c.c")
-`gcc -c -I. -O1 -o cerise-c.o #{"cerise-c.c"}`
+def compile(path)
+ out_path = path.sub(/\.[^.]+$/,'.c')
+ parser = Parser.new(path)
+ checker = TypeChecker.new(parser)
+ codegen = Codegen.new(parser)
+ codegen.output(out_path)
+ `gcc -c -I. -O1 -o cerise-c.o #{out_path}`
+ parser.symbols
+end
+
+#$parser = Parser.new("cerise-c.m")
+#$checker = TypeChecker.new($parser)
+#$codegen = Codegen.new($parser)
+#$codegen.output("cerise-c.c")
+#`gcc -c -I. -O1 -o cerise-c.o #{"cerise-c.c"}`
+
+#pp $parser
+
+pp compile("cerise-c.m")
\ No newline at end of file