private long EvalBinaryAsNumber(string op, EvaluatorState lhs, EvaluatorState rhs) { switch (op) { case "+": return(long.Parse(lhs.Value) + long.Parse(rhs.Value)); case "-": return(long.Parse(lhs.Value) - long.Parse(rhs.Value)); case "*": return(long.Parse(lhs.Value) * long.Parse(rhs.Value)); case "/": return(long.Parse(lhs.Value) / long.Parse(rhs.Value)); case "&": return(long.Parse(lhs.Value) & long.Parse(rhs.Value)); case "|": return(long.Parse(lhs.Value) | long.Parse(rhs.Value)); case "^": return(long.Parse(lhs.Value) ^ long.Parse(rhs.Value)); case "%": return(long.Parse(lhs.Value) % long.Parse(rhs.Value)); case ">>": return(long.Parse(lhs.Value) >> int.Parse(rhs.Value)); case "<<": return(long.Parse(lhs.Value) << int.Parse(rhs.Value)); //Logical shift pad with zeros case ">>>": return(LogicalShift(long.Parse(lhs.Value), int.Parse(rhs.Value))); } throw new ArgumentException("Invalid Operator"); }
private void EvaluateAsmDiv(UnaryASMInstruction div) { EvaluatorState sourceState = null; if (div.Source is LiteralExpression literal) { sourceState = EvaluateLiteralExpression(literal); } else if (div.Source is IdentifierExpression identifier) { sourceState = registers[identifier.Identifier]; } var destState = registers["eax"]; var result = (long.Parse(destState.Value) / long.Parse(sourceState.Value)); destState.Value = result.ToString(); registers["eax"] = destState; if (context.IsExplain) { printer.Print(new Run() { Text = "eax", Color = Colors.White }); PrintAsBitSet((int)long.Parse(destState.Value)); } }
public EvaluatorState Evaluate( AST syntaxTree, ResolvedContext resolved, IPrinter printer, EvaluatorContext context) { this.context = context; this.printer = printer; foreach (var resolvedVariable in resolved.ResolvedVariables) { if (enviroment.Variables.TryGetValue(resolvedVariable.Key, out var varialbe) == false) { enviroment.Variables.Add(resolvedVariable.Key, resolvedVariable.Value); } } EvaluatorState result = null; foreach (var stmt in syntaxTree.Statements) { result = Visit(stmt); if (context.IsExplainAll) { context.IsExplain = true; } if (result.Type == LiteralType.Number && result.Value != null) { printer.Print(new Run() { Text = "=", Color = Colors.Red }); PrintAsBitSet((int)long.Parse(result.Value)); } else if (result.Type == LiteralType.Text && result.Value != null) { printer.Print(new Run() { Text = "=", Color = Colors.Red }); PrintAsText(result.Value); var resultAsNumber = ConvertToNumber(result); PrintAsBitSet((int)long.Parse(resultAsNumber.Value)); } enviroment.Variables["res"] = result; enviroment.StatementIndex++; } return(result); }
private long EvalUnaryAsNumber(string op, EvaluatorState lhs) { switch (op) { case "-": return(-(long.Parse(lhs.Value))); case "~": return(~(long.Parse(lhs.Value))); } throw new ArgumentException("Invalid Operator"); }
private void EvaluateAsmSub(BinaryASMInstruction sub) { EvaluatorState sourceState = EvaluateSource(sub.Source); if (sub.Desination is IdentifierExpression identifierDest) { var destState = registers[identifierDest.Identifier]; var result = (long.Parse(sourceState.Value) - long.Parse(destState.Value)); destState.Value = result.ToString(); registers[identifierDest.Identifier] = destState; if (context.IsExplain) { printer.Print(new Run() { Text = identifierDest.Identifier, Color = Colors.White }); PrintAsBitSet((int)long.Parse(destState.Value)); } } else if (sub.Desination is IndexingExpression indexingDest) { // // Evaluate. // context.IsAssemblyContext = true; var destState = VisitAssemblyInstruction(indexingDest.Expression); context.IsAssemblyContext = false; // // Get the value from the heap. // var offset = (int)long.Parse(destState.Value); var sourceValue = (int)long.Parse(sourceState.Value); var destValue = heap.Read(offset); var result = (sourceValue - destValue); heap.Write(result, offset); if (context.IsExplain) { printer.Print(new Run() { Text = $"[{offset}] : {result}", Color = Colors.White }); PrintAsBitSet(result); } } }
private EvaluatorState EvaluateSource(AST_Node source, bool checkLabels = false) { EvaluatorState state = null; if (source is LiteralExpression literal) { state = EvaluateLiteralExpression(literal); } else if (source is IdentifierExpression identifier) { if (registers.TryGetValue(identifier.Identifier, out var reg)) { state = reg; } else if (enviroment.Variables.TryGetValue(identifier.Identifier, out var variable)) { state = variable; } else if (checkLabels) { if (enviroment.Labels.TryGetValue(identifier.Identifier, out var lbl)) { state = new EvaluatorState() { Value = lbl.ToString() }; } } } else if (source is IndexingExpression indexing) { // // Evaluate. // context.IsAssemblyContext = true; state = VisitAssemblyInstruction(indexing.Expression); context.IsAssemblyContext = false; // // Get the value from the heap. // var value = heap.Read((int)long.Parse(state.Value)); state.Value = value.ToString(); } return(state); }
private EvaluatorState ConvertToNumber(EvaluatorState state) { if (state.Type == LiteralType.Text) { return(new EvaluatorState() { Type = LiteralType.Number, Value = ((int)state.Value[0]).ToString(), IsSigned = true }); } else if (state.Type == LiteralType.Bool) { return(new EvaluatorState() { Type = LiteralType.Number, Value = state.Value == "true" ? "1" : "0", IsSigned = false }); } return(new EvaluatorState()); }
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()}'"); }