private EvaluatorState EvalutateFunctionCallExpression(FunctionCallExpression functionCall) { // // Is built-in function. // switch (functionCall.Name) { case "assert": { var a = Visit(functionCall.Arguments[0]); var b = Visit(functionCall.Arguments[1]); //Error. if (a.Value != b.Value) { return(Error($"Assertion failed for \"{a.Value}\" and \"{b.Value}\"", functionCall)); } break; } } return(EvaluatorState.Empty()); }
private EvaluatorState Visit(AST_Node expression) { // // We either have a tree or a singe AST_Error node here. // So we need to process the error. // if (expression is AST_Error error) { printer.Print(Run.Red($" L:{error.Line} P:{error.Possition} {error.ErrorMessage}")); return(new EvaluatorState()); } else if (expression is AST_Label label) { return(EvaluatorState.Empty()); } if (expression is BinaryExpression operatorExpression) { return(EvaluateBinaryExpression(operatorExpression)); } else if (expression is UnaryExpression unaryExpression) { return(EvaluateUnaryExpression(unaryExpression)); } else if (expression is LiteralExpression literalExpression) { return(EvaluateLiteralExpression(literalExpression)); } else if (expression is IdentifierExpression identifierExpression) { return(EvaluateIdentifierExpression(identifierExpression)); } else if (expression is VariableAssigmentExpression assigmentExpression) { return(EvaluateVariableAssigmentExpression(assigmentExpression)); } else if (expression is ASM_Instruction assemblyInstruction) { return(EvaluateAssemblyInstruction(assemblyInstruction)); } else if (expression is BlockExpression blockExpression) { return(EvaluateBlock(blockExpression)); } else if (expression is FunctionCallExpression functionCall) { return(EvalutateFunctionCallExpression(functionCall)); } else if (expression is CommandExpression commandExpression) { if (commandExpression.CommandName == "explain") { printer.Print(Run.White("Explain is ON")); context.IsExplain = true; return(new EvaluatorState()); } else if (commandExpression.CommandName == "explain_on") { printer.Print(Run.White("Explain is ON")); context.IsExplainAll = true; return(new EvaluatorState()); } else if (commandExpression.CommandName == "explain_off") { printer.Print(Run.White("Explain is OFF")); context.IsExplainAll = false; context.IsExplain = false; return(new EvaluatorState()); } else if (commandExpression.CommandName == "cls") { printer.Clear(); return(new EvaluatorState()); } else if (commandExpression.CommandName == "code") { // // Should be file path; // var path = commandExpression.RightHandSide.ToString(); printer.Clear(); PrintCode(path.Replace("\"", string.Empty)); return(new EvaluatorState()); } else if (commandExpression.CommandName == "parse") { var rhs = commandExpression.RightHandSide; ASTPrinter ast = new ASTPrinter(printer); ast.Print(rhs); return(new EvaluatorState()); } else if (commandExpression.CommandName == "regs") { foreach (var register in registers) { printer.PrintInline(Run.White(register.Key + " :")); PrintAsBitSet((int)long.Parse(register.Value.Value)); } return(new EvaluatorState()); } else if (commandExpression.CommandName == "vars") { int maxVarName = 8; foreach (var variable in enviroment.Variables) { printer.PrintInline( Run.White(variable.Key + new string(' ', Math.Abs(maxVarName - variable.Key.Length)) + " :")); if (variable.Value.Value == null) { printer.Print(Run.Yellow("<NA>")); } switch (variable.Value.Type) { case LiteralType.Number: case LiteralType.Bool: case LiteralType.Text: PrintAsBitSet((int)long.Parse(variable.Value.Value)); break; case LiteralType.Block: PrintAsBlock(); break; } } return(new EvaluatorState()); } else if (commandExpression.CommandName == "mem") { var size = heap.Memory.Length / 4; for (int i = 0; i < size; i++) { var value = heap.Read(i * 4); printer.PrintInline(Run.White(i + " :")); PrintAsBitSet(value); } return(new EvaluatorState()); } return(Visit(commandExpression.RightHandSide)); } throw new ArgumentException($"Invalid Expression: '{expression.ToString()}'"); }