loc = location
expect(:set)
name = identifier()
+ if matches("[")
+ name = array_or_hash_access(name)
+ end
expect ("=")
value = expression()
IR::Set.new(loc, nil, name, value)
# Check for function call
if matches("(")
expr = func_call(expr)
+ elsif matches("[")
+ expr = array_or_hash_access(expr)
end
expr
end
call
end
+ def array_or_hash_access(expr)
+ expect("[")
+ loc = location
+ key = expression()
+ expect("]")
+ make_binop(loc, "[", expr, key)
+
+# def make_binop(loc, op, left, right)
+
+# call = IR::Call.new(location, nil, expr, [])
+# expect("(")
+# while !matches(")")
+# call.args << expression()
+# expect(",") if !matches(")")
+# end
+# expect(")")
+# call
+ end
+
+
def const_or_ident()
if matches("[")
array_literal()
putln state, "#{result} = #{rvar};"
state.indent -= 1
putln state, "}"
+ elsif v.op == "["
+ lvar = emit(state, v.left)
+ rvar = emit(state, v.right)
+ result = mktemp(state);
+ putln state, "Value #{result} = ArrayOrHashGet(#{lvar}, #{rvar});"
else
lvar = emit(state, v.left)
rvar = emit(state, v.right)
end
def self.emit_set(state, v)
- temp = emit(state, v.value)
- raise "invalid local definition: #{v.name.name}" if not state.locals.index(v.name.name)
- putln state, "#{v.name.name} = #{temp};"
+ if v.name.is_a? IR::Op
+ raise "not a valid array or hash access expression" if v.name.op != "["
+ object = emit(state, v.name.left)
+ key = emit(state, v.name.right)
+ value = emit(state, v.value)
+ putln state, "ArrayOrHashSet(#{object}, #{key}, #{value});"
+ else
+ temp = emit(state, v.value)
+ raise "invalid local definition: #{v.name.name}" if not state.locals.index(v.name.name)
+ putln state, "#{v.name.name} = #{temp};"
+ end
end
def self.emit_assert(state, v)