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