public LoopNode(int uniqueId, int uniqueCond, AbstractExpressionNode condition, AbstractStatementNode iteration, AbstractStatementNode statement)
     : base(NodeType.Loop)
 {
     UniqueId    = uniqueId;
     Conditional = new ConditionalNode(uniqueCond, condition, statement, new BlockNode(new BreakNode(UniqueId)));
     Iteration   = iteration;
 }
Exemple #2
0
 public override void OptimizeChilds()
 {
     AddressExpression.OptimizeChilds();
     AddressExpression = AddressExpression.Optimize();
     ValueExpression.OptimizeChilds();
     ValueExpression = ValueExpression.Optimize();
 }
 public static AbstractStatementNode EuclidianDiv(AbstractExpressionNode a, AbstractExpressionNode b) =>
 new CallNode
 (
     new FunctionIdentifierNode(new FunctionSymbol("euclidian_div")),
     a,
     b
 );
Exemple #4
0
 public OperationNode(OperatorType op, AbstractExpressionNode left, AbstractExpressionNode right)
     : base(NodeType.Operation)
 {
     Operator     = op;
     LeftOperand  = left;
     RightOperand = right;
 }
 public static AbstractStatementNode Mod(AbstractExpressionNode a, AbstractExpressionNode b) =>
 new CallNode
 (
     new FunctionIdentifierNode(new FunctionSymbol("mod")),
     a,
     b
 );
Exemple #6
0
 public ConditionalNode(int uniqueId, AbstractExpressionNode expression, AbstractStatementNode trueStatement, AbstractStatementNode falseStatement) : base(NodeType.Conditional)
 {
     UniqueId       = uniqueId;
     Expression     = expression;
     TrueStatement  = trueStatement;
     FalseStatement = falseStatement;
 }
 public static AbstractStatementNode InitArray(AbstractExpressionNode pointer, AbstractExpressionNode dimPointer, AbstractExpressionNode dimPointerSize) =>
 DropReturn(new CallNode
            (
                new FunctionIdentifierNode(new FunctionSymbol("init_array")),
                pointer,
                dimPointer,
                dimPointerSize
            ));
Exemple #8
0
 public PrintExpressionNode(AbstractExpressionNode expression) : base(NodeType.Print)
 {
     Expression = expression;
 }
Exemple #9
0
 public override void OptimizeChilds()
 {
     Expression = Expression.Optimize();
 }
Exemple #10
0
 public AddressableDeclarationNode(AddressableIdentifierNode identifier, AbstractExpressionNode expression) : base(expression)
 {
     Identifier = identifier;
 }
 public ReturnNode(AbstractExpressionNode expression) : base(NodeType.Return)
 {
     Expression = expression;
 }
Exemple #12
0
 public static AbstractExpressionNode Decrement(AbstractExpressionNode node) => new OperationNode(OperatorType.Sub, node, LiteralNode.One);
        private void Generate(AbstractNode node)
        {
            var debugNodeTypes = new NodeType[]
            {
                /*NodeType.Block,
                 * NodeType.Literal,
                 * NodeType.Identifier,
                 * NodeType.Loop,
                 * NodeType.Operation,*/
            };

            if (debugNodeTypes.Contains(node.Type))
            {
                Debug(node.ToString());
            }
            switch (node.Type)
            {
            case NodeType.Block:
                ((BlockNode)node).Statements.ForEach(Generate);
                break;

            case NodeType.Operation:
                var operation = (OperationNode)node;

                // Operations that require two integer as input
                var integerOperations = new[]
                {
                    OperatorType.BitwiseAnd,
                    OperatorType.AndAlso,
                    OperatorType.BitwiseOr,
                    OperatorType.OrElse
                };

                var outputIntegerOperations = new[]
                {
                    OperatorType.Equals,
                    OperatorType.Greater,
                    OperatorType.NotGreater,
                    OperatorType.Less,
                    OperatorType.NotLess,
                    OperatorType.NotEquals
                };

                /*
                 *  We accept floating only, sometimes we need integer (logical and/or)
                 *  In this case, we cast the floating into an integer and cast back the result into a floating one.
                 */
                var requireInteger         = integerOperations.Contains(operation.Operator);
                var requireOutputTransform = outputIntegerOperations.Contains(operation.Operator);

                Generate(operation.LeftOperand);
                if (requireInteger)
                {
                    Write("ftoi");
                }

                Generate(operation.RightOperand);
                if (requireInteger)
                {
                    Write("ftoi");
                }

                switch (operation.Operator)
                {
                case OperatorType.Add:
                    Write("add.f");
                    break;

                case OperatorType.Sub:
                    Write("sub.f");
                    break;

                case OperatorType.Mul:
                    Write("mul.f");
                    break;

                case OperatorType.Div:
                    Write("div.f");
                    break;

                case OperatorType.BitwiseAnd:
                case OperatorType.AndAlso:
                    Write("and");
                    break;

                case OperatorType.BitwiseOr:
                case OperatorType.OrElse:
                    Write("or");
                    break;

                case OperatorType.Equals:
                    Write("cmpeq.f");
                    break;

                case OperatorType.NotEquals:
                    Write("cmpne.f");
                    break;

                case OperatorType.NotGreater:
                    Write("cmple.f");
                    break;

                case OperatorType.Less:
                    Write("cmplt.f");
                    break;

                case OperatorType.NotLess:
                    Write("cmpge.f");
                    break;

                case OperatorType.Greater:
                    Write("cmpgt.f");
                    break;

                case OperatorType.EuclidianDiv:
                    Write(Drop());
                    Write(Drop());
                    Generate(BuiltinFunctions.EuclidianDiv(operation.LeftOperand, operation.RightOperand));
                    break;

                case OperatorType.Mod:
                    Write(Drop());
                    Write(Drop());
                    Generate(BuiltinFunctions.Mod(operation.LeftOperand, operation.RightOperand));
                    break;

                case OperatorType.Pow:
                    Write(Drop());
                    Write(Drop());
                    Generate(BuiltinFunctions.Pow(operation.LeftOperand, operation.RightOperand));
                    break;
                }
                if (requireInteger || requireOutputTransform)
                {
                    Write("itof");
                }
                break;

            case NodeType.Declaration:
                var dcl = (AddressableDeclarationNode)node;
                switch (dcl.Identifier.Symbol.Type)
                {
                case ObjectType.Floating:
                    Generate(dcl.Expression);
                    Write
                    (
                        Set(dcl.Identifier.Symbol.Pointer)
                    );
                    break;

                case ObjectType.Pointer:
                    var indexExpressions = ((MultiExpressionNode)dcl.Expression).Expressions;
                    indexExpressions.Reverse();
                    AbstractExpressionNode finalExpression = LiteralNode.One;
                    for (var i = 0; i < indexExpressions.Count - 1; i++)
                    {
                        finalExpression = new OperationNode
                                          (
                            OperatorType.Mul,
                            new OperationNode
                            (
                                OperatorType.Add,
                                LiteralNode.One,
                                indexExpressions[i]
                            ),
                            finalExpression
                                          );
                    }
                    finalExpression = new OperationNode
                                      (
                        OperatorType.Mul,
                        indexExpressions.Last(),
                        finalExpression
                                      );
                    Generate(BuiltinFunctions.BorrowMemory(finalExpression));
                    Write(Set(dcl.Identifier.Symbol.Pointer));
                    var tempVar = new AddressableIdentifierNode(new PrimitiveVariableSymbol("", PointerIndex + 1));
                    Write(Pushf());
                    Generate(BuiltinFunctions.BorrowMemory(new LiteralNode(indexExpressions.Count)));
                    Write(Set(tempVar.Symbol.Pointer));
                    indexExpressions.Reverse();
                    for (var i = 0; i < indexExpressions.Count; i++)
                    {
                        Generate
                        (
                            new PointerAssignationNode
                            (
                                new OperationNode
                                (
                                    OperatorType.Add,
                                    tempVar,
                                    new LiteralNode(i)
                                ),
                                indexExpressions[i]
                            )
                        );
                    }

                    /*
                     *      var a = bmem(6);
                     *      var b = bmem(2);
                     *      :b = 2;
                     *      :b + 1 = 2;
                     *      init_array(a, b, 2);
                     */
                    Generate(BuiltinFunctions.InitArray(dcl.Identifier, tempVar, new LiteralNode(indexExpressions.Count)));
                    Write(Get(tempVar.Symbol.Pointer));
                    Generate(BuiltinFunctions.RecoverMemory(tempVar));
                    break;
                }
                break;

            case NodeType.Reference:
                var refnode = (ReferenceNode)node;
                Write
                (
                    Pushf(refnode.Identifier.Symbol.Pointer)
                );
                break;

            case NodeType.Dereference:
                var deref = (DereferenceNode)node;
                Generate(deref.Expression);
                Writes
                (
                    Ftoi(),
                    MemRead(),
                    Itof()
                );
                break;

            case NodeType.Assignation:
                var assign = (AssignationNode)node;
                Generate(assign.ValueExpression);
                Write
                (
                    Set(assign.Identifier.Symbol.Pointer)
                );
                break;

            case NodeType.Drop:
                Write(Drop());
                break;

            case NodeType.PointerAssignation:
                var ptrAssign = (PointerAssignationNode)node;
                Generate(ptrAssign.AddressExpression);
                Write
                (
                    Ftoi()
                );
                Generate(ptrAssign.ValueExpression);
                Writes
                (
                    Ftoi(),
                    MemWrite()
                );
                break;

            case NodeType.Literal:
                var lit = (LiteralNode)node;
                Write(Pushf(lit.Value));
                break;

            case NodeType.Identifier:
                var ident = (AddressableIdentifierNode)node;
                Write
                (
                    Get(ident.Symbol.Pointer)
                );
                break;

            case NodeType.Crash:
                Write("halt");
                break;

            case NodeType.Print:
                if (node is PrintExpressionNode)
                {
                    var printe = (PrintExpressionNode)node;
                    Generate(printe.Expression);
                    Write("out.f");
                }
                else
                {
                    var prints = (PrintStringNode)node;
                    foreach (var c in prints.Content)
                    {
                        Write($"push.i {(int)c}");
                        Write("out.c");
                    }
                }
                Write("push.i 10");
                Write("out.c");
                break;

            case NodeType.Loop:
                var loop = (LoopNode)node;
                {
                    Write(DeclareLabel(BeginLoop(loop.UniqueId)));
                    Generate(loop.Conditional);
                    Write(DeclareLabel(IterationLoop(loop.UniqueId)));
                    Generate(loop.Iteration);
                    Write(Jump(BeginLoop(loop.UniqueId)));
                    Write(DeclareLabel(EndLoop(loop.UniqueId)));
                }
                break;

            case NodeType.Break:
                var breakNode = (BreakNode)node;
                Write(Jump(EndLoop(breakNode.LoopId)));
                break;

            case NodeType.Continue:
                var cont = (ContinueNode)node;
                Write(Jump(EndIf(cont.CondId)));
                break;

            case NodeType.Conditional:
                var cond = (ConditionalNode)node;
                {
                    Generate(cond.Expression);
                    Write(JumpFalse(Else(cond.UniqueId)));
                    Generate(cond.TrueStatement);
                    Write(Jump(EndIf(cond.UniqueId)));
                    Write(DeclareLabel(Else(cond.UniqueId)));
                    Generate(cond.FalseStatement);
                    Write(DeclareLabel(EndIf(cond.UniqueId)));
                }
                break;

            case NodeType.MultiExpression:
                var multi = (MultiExpressionNode)node;
                foreach (var expression in multi.Expressions)
                {
                    Generate(expression);
                }
                break;

            case NodeType.Function:
                var fun = (FunctionNode)node;
                Write(DeclareLabel(fun.Identifier.Symbol.Name));
                PointerIndex = fun.Arguments.Count - 1;
                PreGenerate(fun.Statement);
                Generate(fun.Statement);
                if (fun.Identifier.Symbol.Name != "start")
                {
                    Write(Pushf());
                    Write(Ret());
                }
                else
                {
                    Write(Halt());
                }
                break;

            case NodeType.Return:
                var ret = (ReturnNode)node;
                Generate(ret.Expression);
                Write(Ret());
                break;

            case NodeType.Call:
                var call = (CallNode)node;
                Write(Prep(call.Target.Symbol.Name));
                foreach (var arg in call.Parameters)
                {
                    Generate(arg);
                }
                Write(Call(call.Parameters.Count));
                break;

            case NodeType.Root:
                var root = (RootNode)node;
                foreach (var f in root.Functions)
                {
                    Generate(f);
                }
                break;
            }
        }
 public DereferenceNode(AbstractExpressionNode expression) : base(NodeType.Dereference)
 {
     Expression = expression;
 }
 public static AbstractStatementNode BorrowMemory(AbstractExpressionNode size) =>
 new CallNode
 (
     new FunctionIdentifierNode(new FunctionSymbol("bmem")),
     size
 );
Exemple #16
0
 public static AbstractExpressionNode Oppose(AbstractExpressionNode node) => new OperationNode(OperatorType.Sub, LiteralNode.Zero, node);
Exemple #17
0
 public AssignationNode(AddressableIdentifierNode identifier, AbstractExpressionNode value) : base(NodeType.Assignation)
 {
     Identifier      = identifier;
     ValueExpression = value;
 }
Exemple #18
0
 public static AbstractExpressionNode Negate(AbstractExpressionNode node) => new OperationNode(OperatorType.Equals, node, LiteralNode.False);
 public LoopNode(int uniqueId, int uniqueCond, AbstractExpressionNode condition, AbstractStatementNode statement)
     : this(uniqueId, uniqueCond, condition, new BlockNode(), statement)
 {
 }
Exemple #20
0
 public PointerAssignationNode(AbstractExpressionNode address, AbstractExpressionNode value) : base(NodeType.PointerAssignation)
 {
     AddressExpression = address;
     ValueExpression   = value;
 }