private AST.Expression Expression() { var exp = new AST.Expression(); exp.value = Term(); if (Accept(";")) { return(exp); } else if (Accept("=")) { var assignment = new AST.Assignment(); assignment.left = exp.value; assignment.right = Expression(); exp.value = assignment; } else if (Accept(")")) { // the closing Parenthesis might be important to the calling function GoToPreviousSymbol(); return(exp); } else { UnexpectedSymbolError(); } return(exp); }
private AST.Statement Statement() { var statement = new AST.Statement(); if (Accept("if")) { GoToPreviousSymbol(); // let IfStatement() re-read the "if" statement.body = IfStatement(); } else if (Accept("while")) { throw new NotImplementedException(); } else if (Accept("return")) { throw new NotImplementedException(); } else // if nothing matches then we are either in a variable definition or in some assignment { // Variable Definition // This would mean that the next symbol is the type, then after that the name and then either a ";" or an assignment if (Peek(";", 2) || Peek("=", 2) || Peek("const")) { bool is_const = false; if (Accept("const")) { is_const = true; } var type = GetNextSymbol(); var name = GetNextSymbol(); var definition = new AST.VariableDefinition(name, type, is_const); symbol_table.AddDefinition(definition); if (Accept("=")) { var assignment = new AST.Assignment(definition, Expression()); definition.init = assignment; statement.body = definition; } else if (Accept(";")) { statement.body = definition; } else { UnexpectedSymbolError(); } } else if (Peek("=", 1)) { statement.body = Expression(); } else { throw new AST.UnexpectedSymbolException(GetSymbol(2) ?? default(Word)); // This is really shitty } } return(statement); }
private AST.Assignment Assignment() { var assignment = new AST.Assignment(); assignment.left = Expression(); Expect("="); assignment.right = Expression(); return(assignment); }
private AST.Definition Definition() { var definition = new AST.Definition(); // function can be either "static private xyz" or "private static xyz" // and Enforce actually allows a function to be "static private static xyz" if (Accept("static")) { definition.@static = true; } if (Accept("private")) { definition.access_modifier = AccessModifier.@private; } else if (Accept("protected")) { definition.access_modifier = AccessModifier.@protected; } else // default is private { definition.access_modifier = AccessModifier.@private; } if (Accept("static")) { definition.@static = true; } var type = GetNextSymbol(); definition.name = GetNextSymbol(); // now we know it's a function definition if (Accept("(")) { GoToPreviousSymbol(); AST.FunctionDefinition function = new AST.FunctionDefinition(definition); function.return_type = type; symbol_table.AddDefinition(function); function.args = ArgList(); function.body = Block(); return(function); } else { AST.VariableDefinition variable = new AST.VariableDefinition(definition); variable.type = type; symbol_table.AddDefinition(variable); // No Value assigned to the variable if (Accept(";")) { return(variable); } else if (Accept("=")) { var assignment = new AST.Assignment(); assignment.left = variable; assignment.right = Expression(); variable.init = assignment; return(variable); } else { throw new AST.UnexpectedSymbolException(GetLastSymbol()); } } throw new Exception("We should never be here!"); }