public void FindsLocalMember() { var scope = new Sharp_LR35902_Compiler.Scope(); scope.AddMember(TestMember); Assert.IsNotNull(scope.GetLocalMember("test")); }
public void FindsParentMember() { var parentscope = new Sharp_LR35902_Compiler.Scope(); parentscope.AddMember(TestMember); var chiledscope = new Sharp_LR35902_Compiler.Scope(parentscope); Assert.IsNotNull(chiledscope.GetMember("test")); }
public static BlockNode CreateAST(IList <Token> tokens, BlockNode rootnode, ref int i, Scope previousScope) { var currentnode = rootnode; var currentscope = new Scope(previousScope); for (; i < tokens.Count; i++) { var token = tokens[i]; if (token.Type == Variable) { // Variable[++/--] or Variable = [Variable/Immediate] var nexttoken = tokens[++i]; if (nexttoken.Type != Operator) { throw new SyntaxException("Expected operator after variable"); } Token valuenode; VariableMember assignedvariable; switch (nexttoken.Value) { case "=": i++; var expression = CreateExpression(tokens, currentscope, ref i); if (expression == null) { throw new SyntaxException($"Unknown expression after ="); } getVariable(token.Value, currentscope); // Check it exists //var existingvariable = currentscope.GetMember(token.Value); //var immediatedatatype = GetImmedateDataType(expression); //checkCanConvertTypes(immediatedatatype, existingvariable.DataType); currentnode.AddChild(new VariableAssignmentNode(token.Value, expression)); i--; break; case "++": currentnode.AddChild(new IncrementNode(token.Value)); break; case "--": currentnode.AddChild(new DecrementNode(token.Value)); break; case "+=": assignedvariable = getVariable(token.Value, currentscope); valuenode = tokens[++i]; if (valuenode.Type == Variable) { var valuevariable = getVariable(valuenode.Value, currentscope); currentnode.AddChild(new AdditionAssignmentNode(assignedvariable.Name, new VariableValueNode(valuevariable.Name))); } else if (valuenode.Type == Immediate) { var expr = CreateExpression(tokens, currentscope, ref i); i--; currentnode.AddChild(new AdditionAssignmentNode(assignedvariable.Name, new ShortValueNode(expr))); } break; case "-=": assignedvariable = getVariable(token.Value, currentscope); valuenode = tokens[++i]; if (valuenode.Type == Variable) { var valuevariable = getVariable(valuenode.Value, currentscope); currentnode.AddChild(new SubtractionAssignmentNode(assignedvariable.Name, new VariableValueNode(valuevariable.Name))); } else if (valuenode.Type == Immediate) { var exp = CreateExpression(tokens, currentscope, ref i); i--; currentnode.AddChild(new SubtractionAssignmentNode(assignedvariable.Name, new ShortValueNode(exp))); } break; default: throw new SyntaxException("Expected operator"); } } else if (token.Type == DataType) { // DataType Variable = [Variable/Immediate] var variabletoken = tokens[++i]; if (variabletoken.Type != Variable) { throw new SyntaxException("Expected variable name after data type"); } var variabledatatype = BuiltIn.DataTypes.Get(token.Value); if (variabledatatype == null) { throw new SyntaxException($"Datatype {token.Value} does not exist."); } var operatornode = tokens[++i]; if (operatornode.Value == ";" || operatornode.Value == "=") { if (currentscope.GetMember(variabletoken.Value) != null) { throw new SyntaxException($"Variable {variabletoken.Value} already exists in the current scope."); } currentnode.AddChild(new VariableDeclarationNode(token.Value, variabletoken.Value)); if (operatornode.Value == ";") // Just a decleration { currentnode.AddChild(new VariableAssignmentNode(variabletoken.Value, new ShortValueNode(0))); currentscope.AddMember(new VariableMember(variabledatatype, variabletoken.Value)); continue; } } if (operatornode.Value != "=") { throw new SyntaxException("Expected token '='"); } var valuenode = tokens[++i]; var expression = CreateExpression(tokens, currentscope, ref i); if (expression == null) { throw new SyntaxException($"Unexpected symbol on variable assignment '{valuenode.Value}'"); } i--; //var immediatedatatype = GetImmedateDataType(expression); //checkCanConvertTypes(immediatedatatype, variabledatatype); currentnode.AddChild(new VariableAssignmentNode(variabletoken.Value, expression)); currentscope.AddMember(new VariableMember(variabledatatype, variabletoken.Value)); } else if (token.Type == ControlFlow) { switch (token.Value) { case "while": break; case "do": break; case "for": break; case "return": break; case "continue": break; case "else": break; case "if": if (tokens[i + 1].Value != "(") { throw new SyntaxException("Expected expression after IF statement."); } i += 2; var expression = CreateExpression(tokens, currentscope, ref i); if (tokens[i].Value != "{") { throw new SyntaxException("Expected open block after IF statement."); } i++; var iftrue = CreateAST(tokens, new BlockNode(), ref i, currentscope); var iffalse = new BlockNode(); var elsetoken = tokens.Get(++i); if (elsetoken?.Value == "else") { iffalse = CreateAST(tokens, iffalse, ref i, currentscope); } currentnode.AddChild(new IfNode(expression, iftrue, iffalse)); break; case "goto": var nextnode = tokens[++i]; if (nextnode.Type != Variable) { throw new SyntaxException("Expected label name after goto statement."); } currentnode.AddChild(new GotoNode(nextnode.Value)); break; default: // Label var colonindex = token.Value.IndexOf(':'); currentnode.AddChild(new LabelNode(token.Value.Substring(0, colonindex))); break; } } else if (token.Value == "*") { var addresstoken = tokens[++i]; if (addresstoken.Type != Immediate) { throw new SyntaxException("Expected address after pointer."); } var address = ParseImmediate(addresstoken.Value); var equals = tokens[++i]; if (equals.Value != "=") { throw new SyntaxException("Expected assignment after memory address."); } i++; var value = CreateExpression(tokens, currentscope, ref i); currentnode.AddChild(new MemoryAssignmentNode(address, value)); } else if (token.Value == "}") { return(rootnode); } } return(rootnode); }