コード例 #1
0
        private void VisitNode(ClassDeclaration node)
        {
            // catch errors prior to entering class declaration
            ErrorDescriptor err = node.TypeDescriptor as ErrorDescriptor;

            if (err != null)
            {
                PrintError(err);
                return;
            }
            AbstractNode modifiers  = node.Child;
            AbstractNode identifier = modifiers.Sib;
            AbstractNode classBody  = identifier.Sib;

            ClassTypeDescriptor desc =
                node.TypeDescriptor as ClassTypeDescriptor;
            string mods = String.Join(" ", desc.Modifiers).ToLower();
            string name = ((Identifier)identifier).ID;

            ClassName = name;

            File.WriteLine(".assembly extern mscorlib {}");
            File.WriteLine(".assembly addnums {}");
            File.WriteLine(".class {0} {1}", mods, name);
            File.WriteLine("{");
            classBody.Accept(this);
            File.WriteLine("}");
        }
コード例 #2
0
        public ErrorDescriptor CombineErrors(ErrorDescriptor err)
        {
            ErrorDescriptor comboErr = new ErrorDescriptor();

            comboErr.Message = this.Message + "\n" + err.Message;
            return(comboErr);
        }
コード例 #3
0
        private void VisitNode(LocalVariableDeclarationStatement node)
        {
            // catch errors prior to entering local var decl stmt
            ErrorDescriptor err = node.TypeDescriptor as ErrorDescriptor;

            if (err != null)
            {
                PrintError(err);
                return;
            }

            AbstractNode typeSpecifier            = node.Child;
            AbstractNode localVariableDeclarators = typeSpecifier.Sib;

            string        type  = GetIlType(typeSpecifier);
            List <String> names = GetLocalVarDeclNames(localVariableDeclarators);

            SetLocalVarDeclNames(names);

            File.WriteLine(".locals init(");
            int count = 0;
            int location;

            foreach (var name in names)
            {
                location = _localVariables.GetVarLocation(name);
                File.Write($"   [{location}] {type} {name}");
                File.WriteLine((count < names.Count - 1) ? "," : "");
                ++count;
            }
            File.WriteLine(")");
        }
コード例 #4
0
        private string GetIlType(TypeDescriptor desc, AbstractNode typeSpec)
        {
            // either the return type is a primitive (can get from the signature)
            PrimitiveTypeIntDescriptor intDesc =
                desc as PrimitiveTypeIntDescriptor;
            NumberTypeDescriptor numDesc = desc as NumberTypeDescriptor;

            if (intDesc != null || numDesc != null)
            {
                return("int32");
            }
            PrimitiveTypeStringDescriptor stringDesc =
                desc as PrimitiveTypeStringDescriptor;
            LiteralTypeDescriptor litDesc = desc as LiteralTypeDescriptor;

            if (stringDesc != null || litDesc != null)
            {
                return("string");
            }
            PrimitiveTypeBooleanDescriptor boolDesc =
                desc as PrimitiveTypeBooleanDescriptor;

            if (boolDesc != null)
            {
                return("bool");
            }
            PrimitiveTypeVoidDescriptor voidDesc =
                desc as PrimitiveTypeVoidDescriptor;

            if (voidDesc != null)
            {
                return("void");
            }

            // or it is a qualified name (can extract from the node)
            QualifiedName qName = typeSpec as QualifiedName;

            if (qName != null)
            {
                return(qName.GetStringName());
            }

            // or it is an error
            ErrorDescriptor err = desc as ErrorDescriptor;

            if (err != null)
            {
                return(err.Message);
            }

            return("");
        }
コード例 #5
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();
            }
        }
コード例 #6
0
        private string GetIlType(TypeDescriptor desc)
        {
            // either the return type is a primitive (can get from the signature)
            PrimitiveTypeIntDescriptor intDesc =
                desc as PrimitiveTypeIntDescriptor;
            NumberTypeDescriptor numDesc = desc as NumberTypeDescriptor;

            if (intDesc != null || numDesc != null)
            {
                return("int32");
            }
            PrimitiveTypeStringDescriptor stringDesc =
                desc as PrimitiveTypeStringDescriptor;
            LiteralTypeDescriptor litDesc = desc as LiteralTypeDescriptor;

            if (stringDesc != null || litDesc != null)
            {
                return("string");
            }
            PrimitiveTypeBooleanDescriptor boolDesc =
                desc as PrimitiveTypeBooleanDescriptor;

            if (boolDesc != null)
            {
                return("bool");
            }
            PrimitiveTypeVoidDescriptor voidDesc =
                desc as PrimitiveTypeVoidDescriptor;

            if (voidDesc != null)
            {
                return("void");
            }

            // or it is an error
            ErrorDescriptor err = desc as ErrorDescriptor;

            if (err != null)
            {
                return(err.Message);
            }

            return("");
        }
コード例 #7
0
        private ErrorDescriptor CheckModifiers(List <ModifiersEnums> mods)
        {
            string          message;
            ErrorDescriptor error = null;

            if (mods.Contains(ModifiersEnums.PRIVATE) &&
                mods.Contains(ModifiersEnums.PUBLIC))
            {
                message = "Cannot contain both modifiers PUBLIC and PRVATE.";
                error   = new ErrorDescriptor(message);
            }
            if (mods.Count <= 0)
            {
                message = "Must contain at least one modifier PUBLIC, " +
                          "PRIVATE, or STATIC";
                error = new ErrorDescriptor(message);
            }
            return(error);
        }
コード例 #8
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);
            }
        }
コード例 #9
0
        private void VisitNode(MethodCall node)
        {
            AbstractNode methodReference = node.Child;
            AbstractNode argumentList    = methodReference.Sib; // may be null

            TypeDescriptor descriptor;

            QualifiedName qualifiedName = methodReference as QualifiedName;

            if (qualifiedName == null)
            {
                descriptor = new ErrorDescriptor
                                 ("Only Qualified Name supported for Method Call reference");
            }
            else
            {
                // get parameters from method call
                List <TypeDescriptor> argListTypes =
                    GetParameterTypes(argumentList as ArgumentList);

                // get parameters (signature) from declared method
                Attributes           attr             = Table.lookup(qualifiedName.GetStringName());
                MethodTypeDescriptor methodDescriptor =
                    attr.TypeDescriptor as MethodTypeDescriptor;

                if (methodDescriptor != null)
                {
                    SignatureDescriptor methodSignature = methodDescriptor.Signature;

                    if (methodSignature != null &&
                        ParametersMatch(methodSignature, argListTypes))
                    {
                        // method descriptor for only current signature
                        MethodTypeDescriptor temp = new MethodTypeDescriptor();
                        temp.ReturnType = methodDescriptor.ReturnType;
                        temp.Signature.ParameterTypes = argListTypes;
                        temp.Signature.Next           = null;
                        descriptor = temp;
                    }
                    else if (methodSignature == null)
                    {
                        descriptor = new ErrorDescriptor
                                         ("No signature found for method: " +
                                         qualifiedName.GetStringName());
                    }
                    else
                    {
                        descriptor = new ErrorDescriptor
                                         ("No method signature found matching: (" +
                                         String.Join(", ", argListTypes) + ")");
                    }
                }
                else
                {
                    descriptor = new ErrorDescriptor("Method not declared: " +
                                                     qualifiedName.GetStringName());
                }
                node.TypeDescriptor = descriptor;
                Attributes methodCallAttr = new Attr(descriptor);
                methodCallAttr.Kind = Kind.MethodType;
                node.AttributesRef  = methodCallAttr;
            }
        }
コード例 #10
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);
        }
コード例 #11
0
 private void PrintError(ErrorDescriptor node)
 {
     File.WriteLine("call void [mscorlib]System.Console::" +
                    $"WriteLine({node.Message})");
 }