diff --git a/bin/orange b/bin/orange index 8c0cfde..a6b6112 100755 --- a/bin/orange +++ b/bin/orange @@ -18,9 +18,10 @@ if $h end file = ARGV.first -abort "Usage: orange [-hi] [-c=file.o] file.or" unless file +abort "Usage: orange [-hiO] [-c=file.o] file.or" unless file g = Orange.compile(File.read(file)) +g.optimize unless $O case when $i: puts g.inspect diff --git a/lib/orange.rb b/lib/orange.rb index 3f94740..652dceb 100644 --- a/lib/orange.rb +++ b/lib/orange.rb @@ -13,9 +13,18 @@ end module Orange + class ParserError < RuntimeError; end + def self.compile(code) - g = Orange::Generator.new - OrangeParser.new.parse(code).compile(g) - g + generator = Orange::Generator.new + parser = OrangeParser.new + + if node = parser.parse(code) + node.compile(generator) + else + raise ParserError, parser.failure_reason + end + + generator end end diff --git a/lib/orange/generator.rb b/lib/orange/generator.rb index ee589ac..b4a26d2 100644 --- a/lib/orange/generator.rb +++ b/lib/orange/generator.rb @@ -8,6 +8,33 @@ class Generator PCHAR = Type.pointer(Type::Int8Ty) INT = Type::Int32Ty + class Value + STRUCT = LLVM::Type.struct([INT, INT, PCHAR]) + TYPES = [:int, :string, :ptr] + attr_reader :type, :value, :ptr + + def initialize(value, type) + @value = value + @type = type + end + + def alloc(b) + struct = b.alloca(STRUCT, 0) + v = b.struct_gep(struct, 0) + b.store(TYPES.index(@type).llvm, v) + v = case @type + when :int: b.struct_gep(struct, 1) + when :string: b.struct_gep(struct, 2) + end + b.store(@value, v) + @ptr = struct + end + + def load_str(b) + + end + end + def initialize(mod = LLVM::Module.new("orange"), function=nil) @module = mod @locals = {}