Beispiel #1
0
        internal static void DefineFunction(CType signature, string name, CStorageClass cStorageClass)
        {
            //cStorageClass (static, extern, or none)
            //ignore for now

            if (currentFunctionScope != null || BlockScopes.Count > 0)
            {
                throw new SemanticException("can only define function at file scope");
            }
            else
            {
                if (fileScope.ContainsKey(name))
                {
                    if (fileScope[name].functionBody == null && fileScope[name].type.Equals(signature))
                    {
                        fileScope[name].functionBody = CStatment.PopStatement();
                    }
                    else
                    {
                        throw new SemanticException("canot redifein function");
                    }
                }
                else
                {
                    fileScope[name] = new CIdentifier(signature, name, CStatment.PopStatement());
                }
            }
        }
Beispiel #2
0
        public static void EndCompoundStatement(List <CCompoundStatmentItemType> itemTypes)
        {
            CIdentifier.ExitBlockScope();

            List <CStatment> blockBody = new List <CStatment>();

            List <int> localVarSizes = new List <int>();

            //the item types come in sequential order (top to bottom), but they are sitting on the stack in reverse order (botom to top)
            //revers the list to deal with this
            itemTypes.Reverse();
            foreach (var itemType in itemTypes)
            {
                if (itemType == CCompoundStatmentItemType.Statment)
                {
                    CStatment stat = PopStatement();
                    blockBody.Add(stat);
                }
                else
                {
                    CDeclaration decl = CDeclaration.PopDecl();

                    localVarSizes.Add(decl.Size);

                    //get a statments that initilizes the local variable (or does nothing if it is not a definition)
                    blockBody.Add(decl.GetDefinitionStatment());
                }
            }

            //put the statments back in top to bottom order
            blockBody.Reverse();

            PushStatement(new CStatment(blockBody, localVarSizes));
        }
 public override void ExitIterationStatement(CParser.IterationStatementContext context)
 {
     //'while' '(' expression ')' statement
     if (context.GetText().StartsWith("while"))
     {
         SafeCall(context, CStatment.EndWhileLoopStatement);
     }
     //'do' statement 'while' '(' expression ')' ';'
     else if (context.GetText().StartsWith("do"))
     {
         SafeCall(context, CStatment.EndDoWhileLoopStatement);
     }
     else
     {
         //'for' '(' declaration expression? ';' expression? ')' statement
         if (context.declaration() != null)
         {
             SafeCall(context, () => CStatment.EndForLoopStatement(CForInitType.Decl, context.expression(0) != null, context.expression(1) != null));
         }
         //'for' '(' expression? ';' expression? ';' expression? ')' statement
         else
         {
             SafeCall(context, () => CStatment.EndForLoopStatement(context.expression(0) != null ? CForInitType.Expression : CForInitType.None, context.expression(1) != null, context.expression(2) != null));
         }
     }
 }
Beispiel #4
0
 private static void CleanBlock(Dictionary <string, CIdentifier> dictionary)
 {
     foreach (CIdentifier ident in dictionary.Values)
     {
         CStatment.PopLocal(ident.type.Size);
     }
 }
 public override void ExitJumpStatement(CParser.JumpStatementContext context)
 {
     //'goto' Identifier ';'
     if (context.Identifier() != null)
     {
         SafeCall(context, () => CStatment.GotoStatement(context.Identifier().GetText()));
     }
     //'continue' ';'
     else if (context.GetText().StartsWith("continue"))
     {
         SafeCall(context, CStatment.ContinueStatement);
     }
     //'break' ';'
     else if (context.GetText().StartsWith("break"))
     {
         SafeCall(context, CStatment.BreakStatement);
     }
     //'return' expression? ';'
     else if (context.GetText().StartsWith("return"))
     {
         SafeCall(context, () => CStatment.ReturnStatement(context.expression() != null));
     }
     //'goto' unaryExpression ';' -- GCC extension not supported
     else
     {
         SematicError(context, "gcc goto extention not supported");
     }
 }
Beispiel #6
0
        //todo handle scope
        public static CIdentifier CreateIdentifierInCurrentScope(string name, CType cType, CStorageClass StorageClass = CStorageClass.Ignore, CConstType ConstType = CConstType.Ignore)
        {
            if (CType.InStructDefinition)
            {
                //member variable
                CIdentifier ident = new CIdentifier(cType, name, true, false, 0, CType.MemberOffset(cType.Size));
                CType.GlobalStructMembers.Add(ident);
                return(ident);
            }
            else if (BlockScopes.Count > 0)
            {
                if (BlockScopes[BlockScopes.Count - 1].ContainsKey(name))
                {
                    throw new SemanticException("idenitier " + name + " is already defined in this scope");
                }

                //local var
                CIdentifier ident = new CIdentifier(cType, name, false, true, CStatment.PushLocal(cType.Size), 0);
                BlockScopes[BlockScopes.Count - 1][name] = ident;
                return(ident);
            }
            else
            {
                if (fileScope.ContainsKey(name))
                {
                    throw new SemanticException("idenitier " + name + " is already defined in this scope");
                }

                //global var
                CIdentifier ident = new CIdentifier(cType, name, false, false, 0, 0);
                fileScope[name] = ident;
                return(ident);
            }
        }
Beispiel #7
0
        public CStatment GetDefinitionStatment()
        {
            CStatment.BeginCompoundStatement();

            int stats = 0;

            foreach (CIdentifier ident in idents)
            {
                if (ident.Init != null)
                {
                    CStatment.PushStatement(ident.GetDefinitionStatment());
                    stats++;
                }
            }

            List <CCompoundStatmentItemType> items = new List <CCompoundStatmentItemType>();

            for (int i = 0; i < stats; i++)
            {
                items.Add(CCompoundStatmentItemType.Statment);
            }

            CStatment.EndCompoundStatement(items);

            return(CStatment.PopStatement());
        }
Beispiel #8
0
        //function
        public CIdentifier(CType signature, string name, CStatment cStatment)
        {
            //TODO check return type of function
            //TODO (big job) check for "not all paths return a value"

            this.name         = name;
            this.type         = signature;
            this.functionBody = cStatment;
        }
        //STATEMENTS
        //http://en.cppreference.com/w/c/language/statements

        public override void ExitStatement(CParser.StatementContext context)
        {
            if (context.StringLiteral() != null)
            {
                //'asm' '(' StringLiteral ')'';'

                CStatment.AsmStatement(context.StringLiteral().GetText());
            }
        }
Beispiel #10
0
        public static void EndWhileLoopStatement()
        {
            CExpression expr = CExpression.PopExpression();
            CStatment   stat = PopStatement();

            //loopCheck:  if(expression) goto loopBody;
            if (!expr.IsScalar)
            {
                throw new SemanticException("condition expression in loop must be scalar");
            }

            CStatment gotoBody = new CStatment(loopBodyLabels.Peek());

            CExpression.PushExpression(expr);
            PushStatement(gotoBody);
            IfStatement(false);

            CStatment ifCheckGotoBody = PopStatement();

            ifCheckGotoBody.AddLabel(loopChechLabels.Peek().Name);

            //goto endloop:
            CStatment gotoEnd = new CStatment(endLoopLabels.Peek());

            //loopBody:   statment;
            CStatment loopBody = stat;

            loopBody.AddLabel(loopBodyLabels.Peek().Name);

            //goto loopCheck;
            CStatment gotoCheck = new CStatment(loopChechLabels.Peek());

            //endLoop:    {};
            CStatment end = new CStatment();

            end.AddLabel(endLoopLabels.Peek().Name);

            PushStatement(ifCheckGotoBody);
            PushStatement(gotoEnd);
            PushStatement(loopBody);
            PushStatement(gotoCheck);
            PushStatement(end);

            ExitLoop();
            EndCompoundStatement(new List <CCompoundStatmentItemType>
            {
                CCompoundStatmentItemType.Statment,
                CCompoundStatmentItemType.Statment,
                CCompoundStatmentItemType.Statment,
                CCompoundStatmentItemType.Statment,
                CCompoundStatmentItemType.Statment
            }
                                 );

            PushStatement(PopStatement());
        }
 public override void ExitSelectionStatement(CParser.SelectionStatementContext context)
 {
     //'if' '(' expression ')' statement ('else' statement)?
     if (context.GetText().StartsWith("if"))
     {
         SafeCall(context, () => CStatment.IfStatement(context.statement(1) != null));
     }
     //'switch' '(' expression ')' statement
     else
     {
         SafeCall(context, CStatment.EndSwitchStatement);
     }
 }
Beispiel #12
0
        //if statment
        public CStatment(CExpression cExpression, CStatment cStatment)
        {
            string ifBody = CIdentifier.AutoGenerateLabel("ifBody");
            string EndIf  = CIdentifier.AutoGenerateLabel("endIf");

            Add(cExpression);
            Add(new OpCodeEmitter(OpCode.PUSHW, ifBody));
            Add(new OpCodeEmitter(OpCode.JIF));
            Add(new OpCodeEmitter(OpCode.PUSHW, EndIf));
            Add(new OpCodeEmitter(OpCode.JMP));
            Add(new LabelEmitter(ifBody));
            Add(cStatment);
            Add(new LabelEmitter(EndIf));
        }
Beispiel #13
0
        internal static void AsmStatement(string asm)
        {
            string[] parts = asm.Trim('"').Split();

            OpCode code = (OpCode)Enum.Parse(typeof(OpCode), parts[0]);
            string arg  = parts.Length > 1 ? parts[1] : "";

            OpCodeEmitter asmOp = new OpCodeEmitter(code, arg);

            CStatment stat = new CStatment();

            stat.Add(asmOp);

            PushStatement(stat);
        }
 public override void ExitLabeledStatement(CParser.LabeledStatementContext context)
 {
     //Identifier ':' statement
     if (context.Identifier() != null)
     {
         SafeCall(context, () => CStatment.LabeledStatement(context.Identifier().GetText()));
     }
     //'case' constantExpression ':' statement
     else if (context.constantExpression() != null)
     {
         SafeCall(context, CStatment.CaseStatement);
     }
     //'default' ':' statement
     else
     {
         SafeCall(context, CStatment.DefaultStatement);
     }
 }
 public override void EnterIterationStatement(CParser.IterationStatementContext context)
 {
     //beginwhile
     //begindowhile
     //begin for
     if (context.GetText().StartsWith("while"))
     {
         CStatment.BeginWhileLoopStatement();
     }
     //'do' statement 'while' '(' expression ')' ';'
     else if (context.GetText().StartsWith("do"))
     {
         CStatment.BeginDoWhileLoopStatement();
     }
     else
     {
         CStatment.BeginForLoopStatement();
     }
 }
Beispiel #16
0
        //http://en.cppreference.com/w/c/language/if
        public static void IfStatement(bool hasElse)
        {
            //expression must be an expression of any scalar type.
            //If expression compares not equal to the integer zero, statement_true is executed.
            //In the else form, if expression compares equal to the integer zero, statement_false is executed.

            //if ( expression ) statement_true
            if (!hasElse)
            {
                PushStatement(new CStatment(CExpression.PopExpression(), PopStatement()));
            }
            //if ( expression ) statement_true else statement_false
            else
            {
                CStatment els = PopStatement();
                CStatment fi  = PopStatement();

                PushStatement(new CStatment(CExpression.PopExpression(), fi, els));
            }
        }
Beispiel #17
0
        internal CStatment GetDefinitionStatment()
        {
            if (Init == null)
            {
                return(new CStatment());
            }

            if (type.IsStruct)
            {
                throw new SemanticException("local variables of type struct are not implimentd");
            }
            else if (type.IsArray || Init.IsList)
            {
                throw new SemanticException("local variables of type array are not implimentd");
            }
            else if (type.TypeClass == CTypeClass.CFunction)
            {
                throw new InvalidOperationException("wtf how did you declare a local function varable");
            }
            else if (type.TypeClass == CTypeClass.CVoid)
            {
                throw new InvalidOperationException("wtf how did you declare a local void varable");
            }
            else
            {
                OpCode PushOp;

                if (type.Size == 1)
                {
                    PushOp = OpCode.PUSHB;
                }
                else if (type.Size == 2)
                {
                    PushOp = OpCode.PUSHH;
                }
                else if (type.Size == 4)
                {
                    PushOp = OpCode.PUSHW;
                }
                else
                {
                    throw new InvalidOperationException("local variable of unknown size");
                }

                CStatment initilize = new CStatment();
                initilize.Add(new OpCodeEmitter(PushOp, "0"));

                CExpression localAddr = new CExpression(type, ValueCatagory.LValue);

                localAddr.Add(new OpCodeEmitter(OpCode.PUSHBP));
                localAddr.Add(new OpCodeEmitter(OpCode.PUSHW, stackPointerOffset.ToString()));
                localAddr.Add(new OpCodeEmitter(OpCode.ADD));

                CExpression.PushExpression(localAddr);
                CExpression.PushExpression(Init.Expression);

                CExpression.BasicAssignmentOperator();

                initilize.Add(new CStatment(CExpression.PopExpression()));

                return(initilize);
            }
        }
Beispiel #18
0
        public static void EndForLoopStatement(CForInitType initType, bool hasConditionExpression, bool hasIterationExpression)
        {
            List <CCompoundStatmentItemType> compondItems = new List <CCompoundStatmentItemType> {
                CCompoundStatmentItemType.Statment, CCompoundStatmentItemType.Statment
            };

            CStatment loopBody = PopStatement();

            CStatment iterationStatement = hasIterationExpression ? new CStatment(CExpression.PopExpression()) : new CStatment();

            CExpression condition;

            if (hasConditionExpression)
            {
                condition = CExpression.PopExpression();
            }
            else
            {
                CExpression.PushConstant("1");
                condition = CExpression.PopExpression();
            }

            //init_claus

            CStatment initClaus;

            if (initType == CForInitType.Decl)
            {
                initClaus = CDeclaration.PopDecl().GetDefinitionStatment();
            }
            else if (initType == CForInitType.Expression)
            {
                initClaus = new CStatment(CExpression.PopExpression());
            }
            else
            {
                initClaus = new CStatment();
            }

            // contruct loop body
            BeginCompoundStatement();
            PushStatement(loopBody);
            PushStatement(iterationStatement);
            EndCompoundStatement(compondItems);

            CStatment loopbody = PopStatement();

            // while(cond_expression) loopbody
            CExpression.PushExpression(condition);
            PushStatement(loopBody);
            BeginWhileLoopStatement();
            EndWhileLoopStatement();

            CStatment whilestat = PopStatement();

            PushStatement(initClaus);
            PushStatement(whilestat);

            EndCompoundStatement(compondItems);

            PushStatement(PopStatement());
        }
Beispiel #19
0
 public static void PushStatement(CStatment statment)
 {
     statments.Push(statment);
 }
 public override void ExitCompoundStatement(CParser.CompoundStatementContext context)
 {
     //'{' blockItemList? '}'
     SafeCall(context, () => CStatment.EndCompoundStatement(GetBlockItemTypes(context.blockItemList())));
 }