private void VisitNode(TypeSpecifier node) { AbstractNode child = node.Child; // QualifiedName or PrimitiveType child.Accept(TypeVisitor); child.AttributesRef.IsAssignable = true; node.TypeDescriptor = child.TypeDescriptor; }
private void VisitNode(FieldDeclarations node) { AbstractNode fieldDecl = node.Child; while (fieldDecl != null) { fieldDecl.Accept(this); fieldDecl = fieldDecl.Sib; } }
// Call this method to begin the tree printing process public void PrintTree(AbstractNode node, string prefix = "") { if (node == null) { return; } Console.Write(prefix); node.Accept(this); VisitChildren(node, prefix + " "); }
private void VisitNode(Block node) { AbstractNode locVarDeclOrStmt = node.Child; while (locVarDeclOrStmt != null) { locVarDeclOrStmt.Accept(this); locVarDeclOrStmt = locVarDeclOrStmt.Sib; } }
private new void VisitChildren(AbstractNode node) { AbstractNode child = node.Child; while (child != null) { child.Accept(this); child = child.Sib; } }
private void VisitNode(FieldVariableDeclaration node) { AbstractNode modifiers = node.Child; AbstractNode typeSpecifier = modifiers.Sib; AbstractNode fieldVarDecls = typeSpecifier.Sib; typeSpecifier.Accept(TypeVisitor); TypeDescriptor declType = typeSpecifier.TypeDescriptor; List <ModifiersEnums> modifiersList = ((Modifiers)modifiers).ModifierTokens; // note: grammar doesn't allow initialization at declaration // add each identifier in the list to the symbol table AbstractNode fieldVarDeclName = fieldVarDecls.Child; while (fieldVarDeclName != null) { Identifier identifier = fieldVarDeclName.Child as Identifier; if (identifier == null) { string msg = "Expected Identifier type, found " + nameof(identifier); fieldVarDeclName.Child.TypeDescriptor = new ErrorDescriptor(msg); } else { string id = identifier.ID; // if variable already declared locally, assign an error if (Table.isDeclaredLocally(id)) { identifier.TypeDescriptor = new ErrorDescriptor( "Variable name cannot be redeclared: " + id); identifier.AttributesRef = null; } else { VariableDeclarationAttributes attr = new VariableDeclarationAttributes(); attr.Kind = Kind.VariableAttributes; attr.TypeDescriptor = identifier.TypeDescriptor; attr.Modifiers = modifiersList; attr.IsAssignable = true; Table.enter(id, attr); identifier.TypeDescriptor = declType; identifier.AttributesRef = attr; } } fieldVarDeclName = fieldVarDeclName.Sib; } VisitChildren(node); }
private void VisitNode(IterationStatement node) { AbstractNode cond_exp = node.Child; AbstractNode body_stmt = cond_exp.Sib; ++_whileCount; File.WriteLine("br.s {0}{1}", WHILE_COND, _whileCount); File.WriteLine(WHILE_TRUE + _whileCount + ":"); body_stmt.Accept(this); File.WriteLine(WHILE_COND + _whileCount + ":"); cond_exp.Accept(this); File.WriteLine("brtrue.s {0}{1}", WHILE_TRUE, _whileCount); }
private void VisitNode(IterationStatement node) { AbstractNode whileExp = node.Child; AbstractNode bodyStmt = whileExp.Sib; IterationStatementDescriptor iterDesc = new IterationStatementDescriptor(); // while expression whileExp.Accept(this); iterDesc.WhileDescriptor = whileExp.TypeDescriptor; PrimitiveTypeBooleanDescriptor whileBoolDesc = whileExp.TypeDescriptor as PrimitiveTypeBooleanDescriptor; if (whileBoolDesc == null) { iterDesc.TypeDescriptor = new ErrorDescriptor("If statement " + "does not evaluate to a Boolean expression. (Has type: " + GetSimpleName(whileExp.TypeDescriptor) + ")"); } // if body stmt empty, infinite loop error bodyStmt.Accept(this); bodyStmt.TypeDescriptor = bodyStmt.Child.TypeDescriptor; iterDesc.BodyDescriptor = bodyStmt.TypeDescriptor; // propagate up errors as needed if (iterDesc.WhileDescriptor is ErrorDescriptor || iterDesc.BodyDescriptor is ErrorDescriptor) { if (iterDesc.WhileDescriptor is ErrorDescriptor) { iterDesc.TypeDescriptor = iterDesc.WhileDescriptor; if (iterDesc.BodyDescriptor is ErrorDescriptor) { ((ErrorDescriptor)iterDesc.TypeDescriptor).CombineErrors( (ErrorDescriptor)iterDesc.BodyDescriptor); } } else { iterDesc.TypeDescriptor = iterDesc.BodyDescriptor; } } // otherwise assign appropriate iteration statement descriptor else { iterDesc.TypeDescriptor = iterDesc.WhileDescriptor; } node.TypeDescriptor = iterDesc; }
private TypeDescriptor BoolBinaryExp(AbstractNode lhs, AbstractNode rhs, ExpressionEnums op) { lhs.Accept(this); rhs.Accept(this); if (TypesCompatible(lhs.TypeDescriptor, rhs.TypeDescriptor)) { return(new PrimitiveTypeBooleanDescriptor()); } return(new ErrorDescriptor("Comparison of incompatible types: " + GetSimpleName(lhs.TypeDescriptor) + GetOpSymbol(op) + GetSimpleName(rhs.TypeDescriptor))); }
private void VisitNode(ArgumentList node) { if (node == null) { return; } AbstractNode expression = node.Child; while (expression != null) { expression.Accept(this); expression = expression.Sib; } }
private void VisitNode(FieldAccess node) { AbstractNode notJustName = node.Child; AbstractNode identifier = notJustName.Sib; FieldAccessAttributes attr = new FieldAccessAttributes(); notJustName.Accept(this); attr.NotJustNameTypeDescriptor = notJustName.TypeDescriptor; identifier.Accept(this); attr.TypeDescriptor = identifier.TypeDescriptor; node.TypeDescriptor = attr.TypeDescriptor; node.AttributesRef = attr; }
private List <TypeDescriptor> GetParameterTypes(ArgumentList argumentList) { List <TypeDescriptor> types = new List <TypeDescriptor>(); if (argumentList != null) { AbstractNode expression = argumentList.Child; while (expression != null) { expression.Accept(this); types.Add(expression.TypeDescriptor); expression = expression.Sib; } } return(types); }
private void VisitNode(SelectionStatement node) { AbstractNode ifExp = node.Child; AbstractNode thanStmt = ifExp.Sib; AbstractNode elseStmt = thanStmt.Sib; // may be null ifExp.Accept(this); ++_ifCount; File.WriteLine("brfalse.s {0}{1}", IF_FALSE, _ifCount); thanStmt.Accept(this); File.WriteLine("br.s {0}{1}", IF_END, _ifCount); File.WriteLine(IF_FALSE + _ifCount + ":"); elseStmt.Accept(this); File.WriteLine(IF_END + _ifCount + ":"); }
private void VisitNode(ParameterList node) { List <TypeDescriptor> paramTypes = new List <TypeDescriptor>(); AbstractNode parameter = node.Child; while (parameter != null) { parameter.Accept(this); paramTypes.Add(parameter.TypeDescriptor); parameter = parameter.Sib; } ParameterListTypeDescriptor paramListDesc = new ParameterListTypeDescriptor(); paramListDesc.ParamTypeDescriptors = paramTypes; node.TypeDescriptor = paramListDesc; }
// TODO: structs added as requirement // TypeDeclaring (n/a only for array and struct types) private void VisitNode(ClassDeclaration node) { AbstractNode modifiers = node.Child; AbstractNode identifier = modifiers.Sib; AbstractNode classBody = identifier.Sib; ClassTypeDescriptor classDesc = new ClassTypeDescriptor(); classDesc.ClassBody = new ScopeTable(); Modifiers mods = modifiers as Modifiers; if (mods != null) { classDesc.Modifiers = mods.ModifierTokens; } else { node.TypeDescriptor = new ErrorDescriptor("Expected " + "modifier node, found: " + nameof(node)); } Attr attr = new Attr(); attr.Kind = Kind.ClassType; attr.TypeDescriptor = classDesc; string id = ((Identifier)identifier).ID; Table.enter(id, attr); CurrentClass = classDesc; node.TypeDescriptor = classDesc; node.AttributesRef = attr; // push the class body scope table onto the symbol table stack Table.openScope (((ClassTypeDescriptor)attr.TypeDescriptor).ClassBody); AbstractNode fieldDecls = classBody.Child; // grammar allows one class: if body empty, parsing complete if (fieldDecls == null) { return; } fieldDecls.Accept(this); Table.closeScope(); CurrentClass = null; }
private TypeDescriptor EvalBinaryExp(AbstractNode lhs, AbstractNode rhs, ExpressionEnums op) { lhs.Accept(this); rhs.Accept(this); if (TypesCompatible(lhs.TypeDescriptor, rhs.TypeDescriptor)) { // catch two errors if (lhs.TypeDescriptor is ErrorDescriptor && rhs.TypeDescriptor is ErrorDescriptor) { // combine error messages return(((ErrorDescriptor)lhs.TypeDescriptor).CombineErrors ((ErrorDescriptor)rhs.TypeDescriptor)); } // change from number to primitive type int where possible if (lhs.TypeDescriptor is PrimitiveTypeIntDescriptor) { return(lhs.TypeDescriptor); } if (rhs.TypeDescriptor is PrimitiveTypeIntDescriptor) { return(rhs.TypeDescriptor); } // otherwise propagate up matching type return(lhs.TypeDescriptor); } if (lhs.TypeDescriptor is ErrorDescriptor) { return(lhs.TypeDescriptor); } if (rhs.TypeDescriptor is ErrorDescriptor) { return(rhs.TypeDescriptor); } // Otherwise return incompatible types error string err = (GetOpName(op).Length > 0) ? "attempted " + GetOpName(op) + ": " : "attempted: "; err = "Evaluation of incompatible types, " + err + GetSimpleName(lhs.TypeDescriptor) + GetOpSymbol(op) + GetSimpleName(rhs.TypeDescriptor); return(new ErrorDescriptor(err)); }
private void VisitNode(MethodDeclaration node) { // catch errors prior to entering method declaration ErrorDescriptor err = node.TypeDescriptor as ErrorDescriptor; if (err != null) { PrintError(err); return; } _localVariables.OpenScope(); MethodTypeDescriptor desc = node.TypeDescriptor as MethodTypeDescriptor; if (desc != null) { AbstractNode modifiers = node.Child; AbstractNode typeSpecifier = modifiers.Sib; AbstractNode methodDeclarator = typeSpecifier.Sib; AbstractNode methodBody = methodDeclarator.Sib; AbstractNode methodDeclaratorName = methodDeclarator.Child; AbstractNode parameterList = methodDeclaratorName.Sib; // may be null string name = ((Identifier)methodDeclaratorName).ID; if (!desc.Modifiers.Contains(ModifiersEnums.STATIC) /*&& * name.ToLower().Equals("main")*/) { desc.Modifiers.Add(ModifiersEnums.STATIC); } string mods = String.Join(" ", desc.Modifiers).ToLower(); string typeSpec = GetIlType(desc.ReturnType, typeSpecifier); string argList = GetIlTypeParams(desc.Signature.ParameterTypes); string begin = name.ToLower().Equals("main") ? "\n{\n.entrypoint\n.maxstack 42\n" : "\n{\n.maxstack 42"; string end = "ret\n}"; File.WriteLine($".method {mods} {typeSpec} {name}" + $"({argList}) {begin}"); methodBody.Accept(this); File.WriteLine(end); _localVariables.CloseScope(); } }
private void VisitNode(MethodCall node) { // catch errors prior to entering method call ErrorDescriptor err = node.TypeDescriptor as ErrorDescriptor; if (err != null) { PrintError(err); return; } MethodTypeDescriptor desc = node.TypeDescriptor as MethodTypeDescriptor; string retType = GetIlType(desc.ReturnType, node); AbstractNode methodReference = node.Child; AbstractNode argumentList = methodReference.Sib; // may be null QualifiedName qualifiedName = methodReference as QualifiedName; string methodName = qualifiedName.GetStringName(); // add arguments argumentList?.Accept(this); // special calls for Write or WriteLine methods if (methodName.ToLower().Equals("write") || methodName.ToLower().Equals("writeline")) { CallWrites(methodName.ToLower(), GetIlTypeParams(desc.Signature.ParameterTypes)); } // call for declared methods w/in program else { string param = (argumentList == null) ? "" : GetIlTypeParams(argumentList); File.WriteLine("call {0} {1}::{2}({3})", retType, ClassName, methodName, param); } }
public void CreateIlFileContent(AbstractNode node) { node?.Accept(this); }
private void VisitNode(MethodDeclaration node) { AbstractNode modifiers = node.Child; AbstractNode typeSpecifier = modifiers.Sib; AbstractNode methodDeclarator = typeSpecifier.Sib; AbstractNode methodBody = methodDeclarator.Sib; AbstractNode retType = typeSpecifier.Child; if (retType is PrimitiveTypeVoid) { ((PrimitiveTypeVoid)retType).Accept(TypeVisitor); } else if (retType is PrimitiveTypeBoolean) { ((PrimitiveTypeBoolean)retType).Accept(TypeVisitor); } else if (retType is PrimitiveTypeInt) { ((PrimitiveTypeInt)retType).Accept(TypeVisitor); } else if (retType is QualifiedName) { ((QualifiedName)retType).Accept(TypeVisitor); } else { string msg = "Return type of a method must be a " + "PrimitiveType or QualifiedName (found: " + GetSimpleName(retType.TypeDescriptor); retType.TypeDescriptor = new ErrorDescriptor(msg); } AbstractNode methodDeclaratorName = methodDeclarator.Child; AbstractNode parameterList = methodDeclaratorName.Sib; // may be null MethodTypeDescriptor methDesc = new MethodTypeDescriptor(); methDesc.ReturnType = retType.TypeDescriptor; methDesc.Modifiers = ((Modifiers)modifiers).ModifierTokens; methDesc.Locals = new ScopeTable(); methDesc.IsDefinedIn = CurrentClass; Attributes attr = new Attr(methDesc); attr.Kind = Kind.MethodType; string name = ((Identifier)methodDeclaratorName).ID; Table.enter(name, attr); node.TypeDescriptor = attr.TypeDescriptor; node.AttributesRef = attr; Table.openScope(methDesc.Locals); MethodTypeDescriptor oldCurrentMethod = CurrentMethod; CurrentMethod = methDesc; if (parameterList != null) { parameterList.Accept(this); methDesc.Signature.ParameterTypes = ((ParameterListTypeDescriptor) parameterList.TypeDescriptor).ParamTypeDescriptors; attr.TypeDescriptor = methDesc; Table.updateValue(name, attr); node.TypeDescriptor = methDesc; node.AttributesRef = Table.lookup(name); } methodBody.Accept(this); CurrentMethod = oldCurrentMethod; Table.closeScope(); }
private TypeDescriptor AssignmentExp(AbstractNode qualName, AbstractNode exp) { QualifiedName name = qualName as QualifiedName; Expression expression = exp as Expression; PrimaryExpression primaryExp = exp as PrimaryExpression; TypeDescriptor nameDesc; if (name != null && (expression != null || primaryExp != null)) { Attributes nameAttr = Table.lookup(name.GetStringName()); qualName.AttributesRef = nameAttr; qualName.TypeDescriptor = nameAttr.TypeDescriptor; exp.Accept(this); // Check for errors // if both types are Error Descriptors, combine errors ErrorDescriptor nameErrDesc = nameAttr.TypeDescriptor as ErrorDescriptor; ErrorDescriptor expErrDesc = exp.TypeDescriptor as ErrorDescriptor; if (nameErrDesc != null && expErrDesc != null) { nameDesc = nameErrDesc.CombineErrors(expErrDesc); } // if one or the other is an error, propagate the error up else if (nameErrDesc != null) { nameDesc = nameAttr.TypeDescriptor; } else if (expErrDesc != null) { nameDesc = exp.TypeDescriptor; } // check that the variable being assigned to is assignable else if (nameAttr.IsAssignable) { // if types compatible, assign successfully assigned type if (TypesCompatible(nameAttr.TypeDescriptor, exp.TypeDescriptor)) { nameDesc = GetAssignmentDesc(nameAttr.TypeDescriptor, exp.TypeDescriptor); } // otherwise, assign new error for incompatible types else { nameDesc = new ErrorDescriptor("Incompatible types: " + "cannot assign " + GetSimpleName(exp.TypeDescriptor) + " to " + GetSimpleName(nameAttr.TypeDescriptor) + " variable"); } } // variable is not assignable else { nameDesc = new ErrorDescriptor(nameAttr + " is not assigable. Cannot assign as " + GetSimpleName(exp.TypeDescriptor)); } } // Assignment not made up of correct parts else { string message = ""; if (name == null && expression == null) { message += "EQUALS expression expects 'QualifiedName' " + "on LHS, but has: " + qualName.GetType().Name + " & 'Expression' or 'PrimaryExression' on " + "RHS, but has " + exp.GetType().Name; } else if (name == null) { message += "EQUALS expression expects 'QualifiedName' on" + " LHS, but has: " + qualName.GetType().Name; } else { message += "EQUALS expression expects 'Expression' or " + "'PrimaryExpression' on RHS, but has: " + exp.GetType().Name; } nameDesc = new ErrorDescriptor(message); } return(nameDesc); }
private void VisitNode(SelectionStatement node) { AbstractNode ifExp = node.Child; AbstractNode thanStmt = ifExp.Sib; AbstractNode elseStmt = thanStmt.Sib; // may be null SelectionStatementDescriptor ssDesc = new SelectionStatementDescriptor(); String errMsg = ""; // if expression ifExp.Accept(this); ssDesc.IfDescriptor = ifExp.TypeDescriptor; PrimitiveTypeBooleanDescriptor ifBoolDesc = ifExp.TypeDescriptor as PrimitiveTypeBooleanDescriptor; if (ifBoolDesc == null) { ifExp.TypeDescriptor = new ErrorDescriptor("If statement " + "does not evaluate to a Boolean expression. (Has type: " + ifExp.TypeDescriptor.GetType().Name + ")"); } // than statement thanStmt.Accept(this); thanStmt.TypeDescriptor = thanStmt.Child.TypeDescriptor; ssDesc.ThanDescriptor = thanStmt.TypeDescriptor; if (!IsCompatibleStatement(thanStmt.TypeDescriptor)) { if (errMsg.Length > 0) { errMsg += "\n"; } errMsg += "Non-compatible THAN statement type: " + thanStmt.TypeDescriptor.GetType().Name; } // else statement if (elseStmt != null) { elseStmt.Accept(this); ssDesc.HasElseStmt = true; elseStmt.TypeDescriptor = elseStmt.Child.TypeDescriptor; ssDesc.ElseDescriptor = elseStmt.TypeDescriptor; if (!IsCompatibleStatement(elseStmt.TypeDescriptor)) { if (errMsg.Length > 0) { errMsg += "\n"; } errMsg += "Non-compatible ELSE statement type: " + elseStmt.TypeDescriptor.GetType().Name; } } else { ssDesc.HasElseStmt = false; } // if any components have errors, propogate them up the tree if (ifExp.TypeDescriptor is ErrorDescriptor || thanStmt.TypeDescriptor is ErrorDescriptor || elseStmt?.TypeDescriptor is ErrorDescriptor) { // creates an error containing any and all errors lower in tree if (ifExp.TypeDescriptor is ErrorDescriptor) { ssDesc.TypeDescriptor = ifExp.TypeDescriptor; if (thanStmt.TypeDescriptor is ErrorDescriptor) { ((ErrorDescriptor)ssDesc.TypeDescriptor).CombineErrors ((ErrorDescriptor)thanStmt.TypeDescriptor); } if (elseStmt?.TypeDescriptor is ErrorDescriptor) { ((ErrorDescriptor)ssDesc.TypeDescriptor).CombineErrors ((ErrorDescriptor)elseStmt.TypeDescriptor); } } else if (thanStmt.TypeDescriptor is ErrorDescriptor) { ssDesc.TypeDescriptor = thanStmt.TypeDescriptor; if (elseStmt?.TypeDescriptor is ErrorDescriptor) { ((ErrorDescriptor)ssDesc.TypeDescriptor).CombineErrors ((ErrorDescriptor)elseStmt.TypeDescriptor); } } else { ssDesc.TypeDescriptor = elseStmt.TypeDescriptor; } } // if IF/THAN/ELSE was incompatible, create new error else if (errMsg.Length > 0) { ssDesc.TypeDescriptor = new ErrorDescriptor(errMsg); } // otherwise assign evaluated boolean to selection statement desc else { ssDesc.TypeDescriptor = ifExp.TypeDescriptor; } node.TypeDescriptor = ssDesc; }