Beispiel #1
0
        private void VisitNode(TypeSpecifier node)
        {
            AbstractNode child = node.Child;    // QualifiedName or PrimitiveType

            child.Accept(TypeVisitor);
            child.AttributesRef.IsAssignable = true;
            node.TypeDescriptor = child.TypeDescriptor;
        }
Beispiel #2
0
        private void VisitNode(FieldDeclarations node)
        {
            AbstractNode fieldDecl = node.Child;

            while (fieldDecl != null)
            {
                fieldDecl.Accept(this);
                fieldDecl = fieldDecl.Sib;
            }
        }
Beispiel #3
0
 // 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 + "   ");
 }
Beispiel #4
0
        private void VisitNode(Block node)
        {
            AbstractNode locVarDeclOrStmt = node.Child;

            while (locVarDeclOrStmt != null)
            {
                locVarDeclOrStmt.Accept(this);
                locVarDeclOrStmt = locVarDeclOrStmt.Sib;
            }
        }
Beispiel #5
0
        private new void VisitChildren(AbstractNode node)
        {
            AbstractNode child = node.Child;

            while (child != null)
            {
                child.Accept(this);
                child = child.Sib;
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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;
        }
Beispiel #9
0
        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)));
        }
Beispiel #10
0
        private void VisitNode(ArgumentList node)
        {
            if (node == null)
            {
                return;
            }
            AbstractNode expression = node.Child;

            while (expression != null)
            {
                expression.Accept(this);
                expression = expression.Sib;
            }
        }
Beispiel #11
0
        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;
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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 + ":");
        }
Beispiel #14
0
        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;
        }
Beispiel #15
0
        // 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;
        }
Beispiel #16
0
        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));
        }
Beispiel #17
0
        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();
            }
        }
Beispiel #18
0
        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);
            }
        }
Beispiel #19
0
 public void CreateIlFileContent(AbstractNode node)
 {
     node?.Accept(this);
 }
Beispiel #20
0
        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();
        }
Beispiel #21
0
        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);
        }
Beispiel #22
0
        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;
        }