Exemplo n.º 1
0
 public static void Interpret(AstNode program, Environment env)
 {
     if (program.Type != AstNodeType.Program)
     {
         throw new InterpreterException("Expected a program.");
     }
     InterpretStatementList(program.Children, env);
 }
Exemplo n.º 2
0
 private static AstNode LeftAssocCombiner(
     string[] operators,
     ParseFunction termParser,
     TokenStream tokenStream)
 {
     AstNode leftTerm = termParser(tokenStream);
     while (tokenStream.HasMoreTokens && OneOf(tokenStream.Current.Content, operators))
     {
         AstNode tokenNode = new AstNode(AstNodeType.Identifier, tokenStream.Current);
         tokenStream.Next();
         AstNode rightTerm = termParser(tokenStream);
         leftTerm = new AstNode(
             AstNodeType.BinaryExpression,
             new AstNode[] { tokenNode, leftTerm, rightTerm });
     }
     return leftTerm;
 }
Exemplo n.º 3
0
 private static object EvaluateExpression(AstNode astNode, Environment env)
 {
     switch (astNode.Type)
     {
         case AstNodeType.BinaryExpression:
             return EvaluateBinaryExpression(astNode, env);
         case AstNodeType.UnaryExpression:
             return EvaluateUnaryExpression(astNode, env);
         case AstNodeType.FunctionCall:
             return EvaluateFunctionCall(astNode, env);
         case AstNodeType.Number:
             return Int32.Parse(astNode.Token.Content);
         case AstNodeType.FunctionDeclaration:
             return EvaluateFunctionDeclaration(astNode, env);
         case AstNodeType.Identifier:
             return EvaluateIdentifier(astNode, env);
         default:
             throw new InterpreterException(String.Format(
                 "Unknown kind of Expression '{0}'.", astNode.Type));
     }
 }
Exemplo n.º 4
0
 private static object EvaluateBinaryExpression(AstNode astNode, Environment env)
 {
     string binaryOp = astNode.Children[0].Token.Content;
     object rawOperand1 = EvaluateExpression(astNode.Children[1], env);
     object rawOperand2 = EvaluateExpression(astNode.Children[2], env);
     int operand1 = EvaluateInt(rawOperand1);
     int operand2 = EvaluateInt(rawOperand2);
     switch (binaryOp)
     {
         case "+":
             return operand1 + operand2;
         case "-":
             return operand1 - operand2;
         case "*":
             return operand1 * operand2;
         case "/":
             return operand1 / operand2;
         case "<":
             return (operand1 < operand2) ? 1 : 0;
         case "<=":
             return (operand1 <= operand2) ? 1 : 0;
         case "==":
             return (object.Equals(rawOperand1, rawOperand2)) ? 1 : 0;
         case "!=":
             return !(object.Equals(rawOperand1, rawOperand2)) ? 1 : 0;
         case ">=":
             return (operand1 >= operand2) ? 1 : 0;
         case ">":
             return (operand1 > operand2) ? 1 : 0;
         case "||":
             return (TruthFunction(rawOperand1) || TruthFunction(rawOperand2)) ? 1 : 0;
         case "&&":
             return (TruthFunction(rawOperand1) && TruthFunction(rawOperand2)) ? 1 : 0;
     }
     throw new InterpreterException(String.Format(
         "Unknown binary operator '{0}'.", binaryOp));
 }
Exemplo n.º 5
0
        private static object EvaluateFunctionCall(AstNode functionCallNode, Environment env)
        {
            AstNode functionNode = functionCallNode.Children[0];

            if (functionNode.Type == AstNodeType.Identifier)
            {
                string functionName = functionNode.Token.Content;
                if (functionName == "print")
                {
                    // execute our only built-in :-)
                    object valueToPrint = EvaluateExpression(functionCallNode.Children[1], env);
                    if (valueToPrint != null)
                    {
                        Console.WriteLine(valueToPrint.ToString());
                    }
                    else
                    {
                        Console.WriteLine("<null>");
                    }
                    return null;
                }
            }
            FunctionValue function = EvaluateExpression(functionNode, env) as FunctionValue;
            if (function == null)
            {
                throw new InterpreterException("Object is not a function.");
            }

            List<object> argumentValues = new List<object>();
            for (int i = 1; i < functionCallNode.Children.Count; i++)
            {
                AstNode argExpression = functionCallNode.Children[i];
                argumentValues.Add(EvaluateExpression(argExpression, env));
            }

            return function.Call(argumentValues);
        }
Exemplo n.º 6
0
 private static Pair<bool, object> InterpretStatement(AstNode statement, Environment env)
 {
     switch (statement.Type)
     {
         case AstNodeType.FunctionCall:
             return new Pair<bool, object>(
                 true,
                 EvaluateFunctionCall(statement, env));
         case AstNodeType.AssignmentStatement:
             env.AssignLocal(
                 statement.Children[0].Token.Content,
                 EvaluateExpression(statement.Children[1], env));
             return new Pair<bool, object>(true, null);
         case AstNodeType.IfStatement:
             return InterpretIfStatement(statement, env);
         case AstNodeType.CompoundStatement:
             return InterpretStatementList(statement.Children, env);
         case AstNodeType.ReturnStatement:
             return new Pair<bool, object>(
                 false,
                 EvaluateExpression(statement.Children[0], env));
         default:
             throw new InterpreterException(String.Format(
                 "Invalid statement {0}.", statement.Type));
     }
 }
Exemplo n.º 7
0
 private static Pair<bool, object> InterpretIfStatement(AstNode statement, Environment env)
 {
     if (TruthFunction(EvaluateExpression(statement.Children[0], env)))
     {
         return InterpretStatement(statement.Children[1], env);
     }
     else if (statement.Children.Count == 3)
     {
         return InterpretStatement(statement.Children[2], env);
     }
     return new Pair<bool, object>(true, null);
 }
Exemplo n.º 8
0
 private static object EvaluateUnaryExpression(AstNode astNode, Environment env)
 {
     string unaryOp = astNode.Children[0].Token.Content;
     switch (unaryOp)
     {
         case "-":
             return -EvaluateInt(EvaluateExpression(astNode.Children[1], env));
         case "!":
             return !TruthFunction(EvaluateExpression(astNode.Children[1], env)) ? 1 : 0;
     }
     throw new InterpreterException(String.Format(
         "Unknown unary operator '{0}'.", unaryOp));
 }
Exemplo n.º 9
0
 private static object EvaluateIdentifier(AstNode astNode, Environment env)
 {
     string varName = astNode.Token.Content;
     if (varName == "null")
     {
         return null;
     }
     Pair<bool, object> result = env.LookUp(varName);
     if (result.First)
     {
         return result.Second;
     }
     else
     {
         throw new InterpreterException(String.Format(
             "Cannot find variable '{0}'.", varName));
     }
 }
Exemplo n.º 10
0
 private static object EvaluateFunctionDeclaration(AstNode astNode, Environment env)
 {
     List<string> argList = new List<string>();
     foreach (AstNode argNode in astNode.Children[0].Children)
     {
         argList.Add(argNode.Token.Content);
     }
     return new FunctionValue(astNode.Children[1].Children, env, argList);
 }
Exemplo n.º 11
0
 private static AstNode ParseFunctionCallExpression(AstNode function, TokenStream tokenStream)
 {
     MatchToken(TokenType.OpenParen, "(", tokenStream);
     List<AstNode> arguments = ParseExpressionList(tokenStream);
     MatchToken(TokenType.CloseParen, ")", tokenStream);
     arguments.Insert(0, function);
     return new AstNode(AstNodeType.FunctionCall, arguments);
 }
Exemplo n.º 12
0
 private static AstNode ParseExprUnary(TokenStream tokenStream)
 {
     CheckEnd(tokenStream);
     AstNode result;
     if (tokenStream.Current.Type == TokenType.OpenParen)
     {
         result = ParseParenExpression(tokenStream);
     }
     else if (tokenStream.Current.Type == TokenType.Minus
         || tokenStream.Current.Type == TokenType.LogicalNot)
     {
         AstNode tokenNode = new AstNode(AstNodeType.Identifier, tokenStream.Current);
         tokenStream.Next();
         AstNode negatedExpression = ParseExprUnary(tokenStream);
         result = new AstNode(AstNodeType.UnaryExpression, new AstNode[] { tokenNode, negatedExpression });
     }
     else if (tokenStream.Current.Type == TokenType.Identifier)
     {
         AstNode tokenNode = new AstNode(AstNodeType.Identifier, tokenStream.Current);
         tokenStream.Next();
         if (tokenStream.HasMoreTokens && tokenStream.Current.Type == TokenType.OpenParen)
         {
             result = ParseFunctionCallExpression(tokenNode, tokenStream);
         }
         else
         {
             result = tokenNode;
         }
     }
     else if (tokenStream.Current.Type == TokenType.Number)
     {
         result = new AstNode(AstNodeType.Number, tokenStream.Current);
         tokenStream.Next();
     }
     else
     {
         throw new ParserException(String.Format(
             "Expecting an unary expression at {0}.",
             tokenStream.Current.Start));
     }
     while (tokenStream.HasMoreTokens && tokenStream.Current.Type == TokenType.OpenParen)
     {
         result = ParseFunctionCallExpression(result, tokenStream);
     }
     return result;
 }
Exemplo n.º 13
0
 private static AstNode ParseAssignmentStatement(AstNode tok, TokenStream tokenStream)
 {
     MatchToken(TokenType.Equal, "=", tokenStream);
     AstNode value = ParseExpression(tokenStream);
     MatchToken(TokenType.Semicolon, ";", tokenStream);
     return new AstNode(AstNodeType.AssignmentStatement, new AstNode[] { tok, value });
 }
Exemplo n.º 14
0
 private static AstNode ParseAssignmentOrFunctionCallStatement(TokenStream tokenStream)
 {
     CheckEnd(tokenStream);
     AstNode tokenNode = new AstNode(AstNodeType.Identifier, tokenStream.Current);
     tokenStream.Next();
     CheckEnd(tokenStream);
     if (tokenStream.Current.Type == TokenType.Equal)
     {
         return ParseAssignmentStatement(tokenNode, tokenStream);
     }
     else if (tokenStream.Current.Type == TokenType.OpenParen)
     {
         AstNode result = ParseFunctionCallExpression(tokenNode, tokenStream);
         MatchToken(TokenType.Semicolon, ";", tokenStream);
         return result;
     }
     else
     {
         throw new ParserException(String.Format(
             "Expected an assignment or function call at {0}.", tokenNode.Token.Start));
     }
 }