Example #1
0
        public bool CreateModule(CompilerContext context, ProgramUnit programUnit, out Module module)
        {
            bool failed = false;
            module = new Module();
            foreach (MethodDefinition methodDef in programUnit.Methods)
            {
                MethodInfo methodInfo = null;
                TypeDefinition type = null;
                List<TypeDefinition> parameterTypes = new List<TypeDefinition>();
                foreach (var paramDecl in methodDef.Parameters)
                {
                    TypeDefinition paramType = null;
                    if (!this.TryResolveTypeReference(context, paramDecl.Type, out paramType))
                    {
                        return false;
                    }

                    foreach (string paramName in paramDecl.ParameterNames)
                    {
                        parameterTypes.Add(paramType);
                    }
                }

                if (!context.TryFindMethodAndType(
                    methodDef.MethodNameReference,
                    parameterTypes,
                    out type,
                    out methodInfo))
                {
                    string message = string.Format(
                        Properties.Resources.CodeGenerator_UndeclaredMethod,
                        methodDef.MethodNameReference);
                    this.log.Write(new Message(
                        methodDef.Start.Path,
                        methodDef.Start.Line,
                        methodDef.Start.Column,
                        Severity.Error,
                        message));
                    failed = true;
                    continue;
                }

                MethodImpl methodImpl = new MethodImpl(module);
                methodImpl.Method = methodInfo;
                if (this.TryImplementMethod(methodImpl, context, methodDef, type))
                {
                    module.CodeSegment.Add(methodImpl);
                }
                else
                {
                    failed = true;
                }
            }

            return !failed;
        }
Example #2
0
 public MethodImpl(Module module)
 {
     this.Module = module;
 }
Example #3
0
 public abstract bool Write(Module module);
Example #4
0
        public override bool Write(Module module)
        {
            writer.WriteLine(".model flat,C");
            writer.WriteLine();
            foreach (MethodInfo method in module.ProtoList)
            {
                writer.Write(method.MangledName);
                writer.WriteLine(" PROTO C");
            }

            foreach (string externSymbol in module.ExternList)
            {
                writer.Write(externSymbol);
                writer.WriteLine(" PROTO C");
            }

            writer.WriteLine();
            writer.WriteLine(".data");
            foreach (DataEntry dataEntry in module.DataSegment)
            {
                if (!string.IsNullOrEmpty(dataEntry.Label))
                {
                    writer.Write(dataEntry.Label);
                }

                for (int i = 0; i < dataEntry.Value.Length; i++)
                {
                    writer.Write("\t");
                    object val = dataEntry.Value[i];
                    if (val is byte)
                    {
                        writer.Write("db");
                    }
                    else if (val is ushort)
                    {
                        writer.Write("dw");
                    }
                    else
                    {
                        writer.Write("dd");
                    }

                    writer.Write("\t");

                    writer.WriteLine(val);
                }

                writer.WriteLine();
            }

            writer.WriteLine();
            writer.WriteLine(".code");
            string mainMethod = null;
            foreach (MethodImpl method in module.CodeSegment)
            {
                if (method.Method.IsStatic &&
                   string.CompareOrdinal("Main", method.Method.Name) == 0 &&
                   method.Method.Parameters.Count == 2 &&
                   string.CompareOrdinal(method.Method.Parameters[0].Type.FullName, "integer") == 0 &&
                   string.CompareOrdinal(method.Method.Parameters[1].Type.FullName, "#0#0character") == 0)
                {
                    mainMethod = method.Method.MangledName;
                }

                foreach (string symbol in method.Symbols.Keys)
                {
                    writer.WriteLine("{0}={1}", symbol, method.Symbols[symbol]);
                }

                writer.Write(method.Method.MangledName);
                writer.Write(" PROC C");
                if (method.Method.IsProtected || method.Method.IsPublic)
                {
                    writer.Write(" EXPORT");
                }

                writer.WriteLine();

                foreach (var statement in method.Statements)
                {
                    if (!string.IsNullOrEmpty(statement.Label))
                    {
                        writer.Write("{0}:", statement.Label);
                    }

                    writer.Write("\t");
                    writer.WriteLine(statement.Instruction);
                }

                writer.Write(method.Method.MangledName);
                writer.WriteLine(" ENDP");
            }

            if (!string.IsNullOrEmpty(mainMethod))
            {
                string methodText = @"wmain PROC C EXPORT
            push ebp
            mov ebp,esp
            push [ebp+12]
            push [ebp+8]
            call {0}
            add esp,8
            mov esp,ebp
            pop ebp
            ret
            wmain ENDP";

                writer.WriteLine(methodText, mainMethod);
            }

            writer.WriteLine("END");
            return true;
        }