--- /dev/null
+#include <runtime.h>
+
+Value Int_SumInts(Value a, Value b);
+
+Value Int_SumInts(Value a, Value b) {
+ Value _t0 = OpAdd(a, b);
+ return _t0;
+}
+
--- /dev/null
+module Int
+
+SumInts(a : int, b : int) : int
+{
+ return a + b
+}
module TestSuite
imports (
- "foo/bar/baz"
+ "Int.m"
)
exports (Main)
TestGtEqOps()
TestNeqOps()
TestIfBlocks()
+ Int.SumInts(1,2)
}
require_relative 'lib/codegen'
require_relative 'lib/compiler'
-pp Compiler.compile("cerise-c.m")
\ No newline at end of file
+ARGV.each {|p| Compiler.compile(p) }
\ No newline at end of file
module Compiler
+ PATH = [
+ ".",
+ "#{ENV["HOME"]}/lib/cerise",
+ "/usr/share/cerise",
+ "/usr/local/share/cerise"
+ ]
+
def self.compile(path)
out_path = path.sub(/\.[^.]+$/,'.c')
parser = Parser.new(path)
codegen = Codegen.new(parser)
codegen.output(out_path)
`gcc -c -I. -O1 -o cerise-c.o #{out_path}`
- parser.symbols
+ Value::Module.new(parser.module, parser.symbols)
+ end
+
+ def self.import(path)
+ PATH.each do |root|
+ p = "#{root}/#{path}"
+ puts p
+ if File.exist?(p)
+ return Compiler.compile(p)
+ end
+ end
+ raise "could not find #{path} in search paths"
end
end
\ No newline at end of file
@imports = []
expect("(")
while !matches(")")
- @imports << module_path()
+ modpath = module_path()
+ mod = Compiler.import(modpath)
+ syms.add_builtin(
+ mod.name,
+ :module,
+ mod,
+ nil
+ )
+ @imports << modpath
expect(",") if not matches(")")
end
expect(")")
elsif tok.type == :void
IR::Const.new(tok.pos, :void, :void)
elsif tok.type == :ident
- IR::Var.new(tok.pos, nil, tok.text.to_sym)
+ varname = IR::Var.new(tok.pos, nil, tok.text.to_sym)
+ if accept(".")
+ tok = consume()
+ field = IR::Var.new(tok.pos, nil, tok.text.to_sym)
+ varname = make_binop(varname.loc, ".", varname, field)
+ end
+ varname
else
error("invalid constant #{tok}")
end
type = infer(env, expr.func)
end
+ # Handle module references here
+ if expr.func.type.is_a? Value::Module
+ pp "MODULE!!!"
+ pp expr
+ end
+
error(expr.loc, "object being applied is not a function (has type: #{type.to_s})") if not type.is_a? Array
error(expr.loc, "wrong number of arguments to function call") if (type.length - 1) != expr.args.length
type[0..-2].each_with_index do |t,i|
end
def check_binary(env, expr, vtype)
- if expr.op == "["
+ if expr.op == "."
+ left_type = infer(env, expr.left)
+ if not left_type.is_a? Value::Module
+ error(expr.loc, "left side of '.' is not a module or record")
+ end
+ elsif expr.op == "["
left_type = infer(env, expr.left)
if (left_type.is_a? Value::Type) and left_type.form == :array
check(env, expr.right, :int)
Type = Struct.new(:form, :fields, :base, :size)
Field = Struct.new(:type, :offset)
+ Module = Struct.new(:name, :exports)
+
# Base type definitions
Void = Type.new(:void, nil, nil, 0)
Bool = Type.new(:bool, nil, nil, 1)