private AST Convert(AST candidate) { switch (candidate.Type) { case TreeType.IDENTIFIER: return(candidate.Evaluate(this.env)); case TreeType.FUNCTION_CALL: return(candidate.Evaluate(this.env)); default: return(candidate); } }
private AST ApplyPLUS(Token oparata, AST op1, AST op2) { AST firstType = op1.Evaluate(this.env); AST secondType = op2.Evaluate(this.env); if (checkType(firstType, TreeType.NUMBER) && checkType(secondType, TreeType.NUMBER)) { //Both are numbers Number first = firstType as Number; Number second = secondType as Number; return(new Tree.Number((first.Value + second.Value).ToString())); } else if (checkType(firstType, TreeType.STRING) && checkType(secondType, TreeType.STRING)) { //Concat strings Tree.String first = firstType as Tree.String; Tree.String second = secondType as Tree.String; return(new Tree.String(first.Value + second.Value)); } else { this.Error("Operator + cannot be applied to operands of type " + op1.Type + " and " + op2.Type, oparata.Row, oparata.Column); return(new Null()); } }
public override dynamic Solve(Env.Environment env) { Env.Environment environ = Env.Environment.Scope(env); AST value = environ.Get(this.Parameters[0]); dynamic print = ""; if (value.Type == TreeType.LIST) { print = value.Evaluate(environ).ToString(); } else if (value.Type == TreeType.LIST_ACCESS) { print = value.Evaluate(env).ToString(); } else { print = value.Evaluate(environ).Value; } using (StreamWriter writer = new StreamWriter(Console.OpenStandardOutput())) { writer.Write(print.ToString() + "\n"); } return(value); }
public override dynamic Evaluate(Env.Environment env) { if (this.right.Type == TreeType.LIST) { Tree.List right = this.right as List; List <AST> items = new List <AST>(); foreach (AST item in right.Items) { items.Add(item.Evaluate(env)); } this.right = new Tree.List(items); } AST final = this.right.Evaluate(env); if (final.Type == TreeType.LIST_ACCESS) { final = final.Evaluate(env); } env.Set(this.left, final); return(this.right); }
public AST Apply(Token operata, AST op1, AST op2) { op1 = this.Convert(op1); if (!operata.Is(TokenType.FULL_STOP)) { op2 = this.Convert(op2); } switch (operata.Type) { case TokenType.TIMES: return(new Tree.Number((op1.Evaluate(this.env).Value *op2.Evaluate(this.env).Value).ToString())); case TokenType.DIVIDE: return(new Tree.Number((op1.Evaluate(this.env).Value / op2.Evaluate(this.env).Value).ToString())); case TokenType.PLUS: return(this.ApplyPLUS(operata, op1, op2)); case TokenType.MINUS: return(new Tree.Number((op1.Evaluate(this.env).Value - op2.Evaluate(this.env).Value).ToString())); case TokenType.MODULUS: return(new Tree.Number((op1.Evaluate(this.env).Value % op2.Evaluate(this.env).Value).ToString())); case TokenType.EQUAL_TO: return(new Tree.Boolean((op1.Evaluate(this.env).Value == op2.Evaluate(this.env).Value).ToString())); case TokenType.NOT_EQUAL_TO: return(new Tree.Boolean((op1.Evaluate(this.env).Value != op2.Evaluate(this.env).Value).ToString())); case TokenType.LESS_THAN: return(new Tree.Boolean((op1.Evaluate(this.env).Value < op2.Evaluate(this.env).Value).ToString())); case TokenType.LESS_THAN_OR_EQUAL_TO: return(new Tree.Boolean((op1.Evaluate(this.env).Value <= op2.Evaluate(this.env).Value).ToString())); case TokenType.GREATER_THAN: return(new Tree.Boolean((op1.Evaluate(this.env).Value > op2.Evaluate(this.env).Value).ToString())); case TokenType.GREATER_THAN_OR_EQUAL_TO: return(new Tree.Boolean((op1.Evaluate(env).Value >= op2.Evaluate(env).Value).ToString())); case TokenType.LOGICAL_AND: var op1Res = op1.Evaluate(this.env).Value; var op2Res = op2.Evaluate(this.env).Value; return(new Tree.Boolean((op1Res && op2Res).ToString())); case TokenType.LOGICAL_OR: var operationOneRes = op1.Evaluate(this.env).Value; var operationTwoRes = op2.Evaluate(this.env).Value; return(new Tree.Boolean((operationOneRes || operationTwoRes).ToString())); case TokenType.FULL_STOP: return(this.AccessModifier(op1, op2)); default: this.Error(operata.Type + " cannot be used as an expression operator", operata.Row, operata.Column); return(null); } }