private MObject EvalMinusPrefixOperatorExpression(MObject right) { if (right.MType() != ObjectType.INTEGER_OBJ) { return(NewError(string.Format("unknown operator: -%s", right.MType()))); } var val = ((MInt)right).value; return(new MInt() { value = -val }); }
private bool IsError(MObject obj) { if (obj == null) { return(false); } return(obj.MType() == ObjectType.ERROR_OBJ); }
private MObject EvalPrefixExpression(string op, MObject right, Environment env) { switch (op) { case "!": return(EvalBangOperatorExpression(right)); case "-": return(EvalMinusPrefixOperatorExpression(right)); default: return(NewError(string.Format("unknown operator: %s%s", op, right.MType()))); } }
private MObject EvalInfixExpression(string op, MObject left, MObject right, Environment env) { if (left.MType() == ObjectType.INTEGER_OBJ && right.MType() == ObjectType.INTEGER_OBJ) { return(EvalIntegerInfixExpression(op, left, right)); } else if (op == "==") { return(NativeBoolToMBool(left == right)); } else if (op == "!=") { return(NativeBoolToMBool(left != right)); } else if (left.MType() != right.MType()) { return(NewError(string.Format("type mismatch: %s %s %s", left.MType(), op, right.MType()))); } else { return(NewError(string.Format("unknown operator: %s %s %s", left.MType(), op, right.MType()))); } }
private MObject EvalIntegerInfixExpression(string op, MObject left, MObject right) { var lv = ((MInt)left).value; var rv = ((MInt)right).value; switch (op) { case "+": return(new MInt() { value = lv + rv }); case "-": return(new MInt() { value = lv - rv }); case "*": return(new MInt() { value = lv * rv }); case "/": return(new MInt() { value = lv / rv }); case ">": return(NativeBoolToMBool(lv > rv)); case "<": return(NativeBoolToMBool(lv < rv)); case "==": return(NativeBoolToMBool(lv == rv)); case "!=": return(NativeBoolToMBool(lv != rv)); default: return(NewError(string.Format("unknown operator: %s %s %s", left.MType(), op, right.MType()))); } }
private MObject EvalBlockStatement(BlockStatement block, Environment env) { MObject rs = null; foreach (var statement in block.Statements) { rs = Eval(statement, env); if (rs != null) { var t = rs.MType(); if (t == ObjectType.RETURN_VALUE_OBJ || t == ObjectType.ERROR_OBJ) { return(rs); } } } return(rs); }