lib/liquidscript/compiler/icr/expressions.rb in liquidscript-0.0.1 vs lib/liquidscript/compiler/icr/expressions.rb in liquidscript-0.1.0

- old
+ new

@@ -6,26 +6,50 @@ # Compiles an expression. This is primarily used in a general # context, such that anything can be returned. # # @return [ICR::Code] def compile_expression - expect :number, :identifier, - :dstring, :lparen, - :sstring, :keyword, - :lbrack => :object, - :lbrace => :array, - :arrow => :function + expect :if, :unless, :class, :module, :_ => :vexpression end + # Compiles an expression that returns a value. + # + # @return [ICR::Code] + def compile_vexpression + out = expect :number, :identifier, + :dstring, :lparen, + :sstring, :operator, + :keyword, :unop, + :lbrack => :object, + :lbrace => :array, + :arrow => :function + + if peek? :binop + compile_binop out + elsif peek? :prop + compile_property(out) + else + out + end + end + + def compile_binop(left) + code :binop, shift(:binop), left, compile_vexpression + end + + def compile_unop + code :unop, shift(:unop), compile_vexpression + end + # Handles an assignment of the form `identifier = expression`, # with the argument being the identifier, and the position of # the compiler being after it. # # @return [ICR::Code] def compile_assignment(identifier) shift :equal - value = compile_expression + value = compile_vexpression if identifier.type == :identifier variable = set(identifier) variable.value = value else @@ -50,11 +74,11 @@ maybe_func = 0 end expression = action do maybe_func = 0 - components << compile_expression + components << compile_vexpression end loop do case maybe_func when 0 @@ -84,9 +108,47 @@ else c end end) end + end + + [:if, :elsif].each do |key| + define_method(:"compile_#{key}") do + shift key + shift :lparen + conditional = compile_vexpression + shift :rparen + shift :lbrack + + body = collect_compiles(:expression, :rbrack) + + if peek?(:elsif, :else) + code key, conditional, body, expect(:elsif, :else) + else + code key, conditional, body + end + end + end + + def compile_unless + shift :unless + shift :lparen + conditional = compile_vexpression + shift :rparen + shift :lbrack + + body = collect_compiles(:expression, :rbrack) + code :unless, conditional, body + end + + def compile_else + shift :else + shift :lbrack + + body = collect_compiles(:expression, :rbrack) + + code :else, body end end end end