diff --git a/lib/arm/arm_machine.rb b/lib/arm/arm_machine.rb index e6f19f08..5f1ce2a1 100644 --- a/lib/arm/arm_machine.rb +++ b/lib/arm/arm_machine.rb @@ -46,6 +46,10 @@ module Arm block << sub( result , left , right ) result end + def integer_left_shift block , result , left , right + block << mov( result , left , shift_lsr: right ) + result + end def function_call into , call raise "Not CallSite #{call.inspect}" unless call.is_a? Vm::CallSite diff --git a/lib/ast/basic_expressions.rb b/lib/ast/basic_expressions.rb index d225af13..2f87f421 100644 --- a/lib/ast/basic_expressions.rb +++ b/lib/ast/basic_expressions.rb @@ -53,7 +53,9 @@ module Ast def inspect self.class.name + '.new("' + string + '")' end - + def to_s + '"' + string + '"' + end def compile context , into value = Vm::StringConstant.new(string) context.object_space.add_object value diff --git a/lib/ast/function_expression.rb b/lib/ast/function_expression.rb index dae94360..806c47cc 100644 --- a/lib/ast/function_expression.rb +++ b/lib/ast/function_expression.rb @@ -17,7 +17,9 @@ module Ast end def to_s - "def #{name}( " + params.join(",") + ") \n" + body.join("\n") + "end\n" + ret = "def " + ret += "#{receiver}." if receiver + ret + "#{name}( " + params.join(",") + ") \n" + body.join("\n") + "end\n" end def compile context , into raise "function does not compile into anything #{self}" if into @@ -31,6 +33,7 @@ module Ast end class_name = context.current_class.name function = Vm::Function.new(name , args ) + # class depends on receiver context.current_class.add_function function parent_locals = context.locals @@ -41,8 +44,8 @@ module Ast into = function.body last_compiled = nil body.each do |b| + puts "compiling in function #{b}" last_compiled = b.compile(context , into) - puts "compiled in function #{last_compiled.inspect}" raise "alarm #{last_compiled} \n #{b}" unless last_compiled.is_a? Vm::Word end diff --git a/lib/ast/if_expression.rb b/lib/ast/if_expression.rb index 2a48d589..26098cd0 100644 --- a/lib/ast/if_expression.rb +++ b/lib/ast/if_expression.rb @@ -18,23 +18,23 @@ module Ast true_block = false_block.new_block "#{into.name}_if_true" merge_block = true_block.new_block "#{into.name}_if_merge" + puts "compiling if condition #{cond}" cond_val = cond.compile(context , into) - puts "compiled if condition #{cond_val.inspect}" into.b true_block , condition_code: cond_val.operator if_false.each do |part| + puts "compiling in if false #{part}" last = part.compile(context , false_block ) - puts "compiled in if false #{last.inspect}" end false_block.b merge_block last = nil if_true.each do |part| + puts "compiling in if true #{part}" last = part.compile(context , true_block ) - puts "compiled in if true #{last.inspect}" end - puts "compile if end" + puts "compiled if: end" into.insert_at merge_block return last diff --git a/lib/ast/module_expression.rb b/lib/ast/module_expression.rb index 5a599a27..101da84e 100644 --- a/lib/ast/module_expression.rb +++ b/lib/ast/module_expression.rb @@ -22,7 +22,7 @@ module Ast # check if it's a function definition and add # if not, execute it, but that does means we should be in crystal (executable), not ruby. ie throw an error for now raise "only functions for now #{expression.inspect}" unless expression.is_a? Ast::FunctionExpression - puts "compiling expression #{expression.inspect}" + puts "compiling expression #{expression}" expression_value = expression.compile(context , nil ) #puts "compiled expression #{expression_value.inspect}" end diff --git a/lib/ast/operator_expressions.rb b/lib/ast/operator_expressions.rb index c0a78b29..fc32593c 100644 --- a/lib/ast/operator_expressions.rb +++ b/lib/ast/operator_expressions.rb @@ -16,9 +16,9 @@ module Ast "#{left} #{operator} #{right}" end def compile context , into - puts "compile operator #{to_s}" + puts "compiling operator #{to_s}" r_val = right.compile(context , into) - puts "compiled right #{r_val.inspect}" + #puts "compiled right #{r_val.inspect}" if operator == "=" # assignment, value based raise "Can only assign variables, not #{left}" unless left.is_a?(NameExpression) l_val = context.locals[left.name] @@ -52,6 +52,9 @@ module Ast when "-" res = context.function.new_local code = res.minus into , l_val , r_val + when "<<" + res = context.function.new_local + code = res.left_shift into , l_val , r_val else raise "unimplemented operator #{operator} #{self}" end diff --git a/lib/ast/return_expression.rb b/lib/ast/return_expression.rb index d3837400..6646fa00 100644 --- a/lib/ast/return_expression.rb +++ b/lib/ast/return_expression.rb @@ -14,8 +14,8 @@ module Ast [:expression] end def compile context , into + puts "compiling return expression #{expression}, now return in 7" expression_value = expression.compile(context , into) - puts "compiled return expression #{expression_value.inspect}, now return in 7" # copied from function expression: TODO make function return_reg = Vm::Integer.new(7) diff --git a/lib/ast/while_expression.rb b/lib/ast/while_expression.rb index fbe9f412..dff03d5b 100644 --- a/lib/ast/while_expression.rb +++ b/lib/ast/while_expression.rb @@ -16,13 +16,13 @@ module Ast def compile context , into while_block = into.new_block "#{into.name}_while" ret = while_block.new_block "#{into.name}_return" + puts "compiling while condition #{condition}" cond_val = condition.compile(context , while_block) - puts "compiled while condition #{cond_val.inspect}" while_block.b ret , condition_code: cond_val.not_operator last = nil body.each do |part| + puts "compiling in while #{part}" last = part.compile(context , while_block ) - puts "compiled in while #{last.inspect}" end while_block.b while_block puts "compile while end" diff --git a/lib/vm/values.rb b/lib/vm/values.rb index 7bc8e36b..c9cdcb68 100644 --- a/lib/vm/values.rb +++ b/lib/vm/values.rb @@ -127,6 +127,9 @@ module Vm def minus block , first , right RegisterMachine.instance.integer_minus block , self , first , right end + def left_shift block , first , right + RegisterMachine.instance.integer_left_shift block , self , first , right + end def load block , right if(right.is_a? IntegerConstant)