Esempio n. 1
0
        private CompilerContext Term(CompilerContext context)
        {
            var rootNode = context.Node[0];

            if (rootNode.Is(_grammar.unary_expression))
            {
                context.Compile(rootNode[1]);
                context.Compile(rootNode[0]);
            }
            else
            {
                context.Compile(rootNode);
            }

            return(context);
        }
Esempio n. 2
0
        private CodeStream Compile(CompilerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var rule = context.Node.GetRule();

            if (!rule.IsUnnamed())
            {
                Func <CompilerContext, CompilerContext> codeGenerator;
                if (!_codeGenerator.TryGetValue(rule, out codeGenerator))
                {
                    throw new InvalidOperationException("Cannot find code generator: " + rule.RuleName);
                }

                if (codeGenerator != null)
                {
                    codeGenerator(context);
                    return(context.Code);
                }
            }

            foreach (var node in context.Node)
            {
                context.Compile(node);
            }

            return(context.Code);
        }
Esempio n. 3
0
        private CompilerContext IfStatement(CompilerContext context)
        {
            var ifFalse = Enumerable.Empty <Instruction>();

            var expression = context.Node.GetNamedChild("if_condition").GetNamedChild("relational_expression");

            context.Compile(expression);
            var jumpCode = context.JumpExpression;

            var        block  = context.Node.GetNamedChild("block");
            var        child  = context.Push(block);
            CodeStream ifTrue = child.Compiler(child);

            var elseBlock = context.Node.GetNamedChild("else_block");

            if (elseBlock != null)
            {
                block   = elseBlock.GetNamedChild("block");
                child   = context.Push(block);
                ifFalse = child.Compiler(child);
                ifTrue.AsFluent()
                .Jmp.I(ifFalse.Count() + 1);
            }

            context.Code.AsFluent()
            .UnaryOp(jumpCode).I(ifTrue.Count() + 1);

            context.Code += ifTrue;
            context.Code += ifFalse;

            return(context);
        }
Esempio n. 4
0
        private static CompilerContext CompileExpression(CompilerContext context, params Tuple <string, Action <FluentWriter>, OpCode>[] codeWriters)
        {
            context.Compile(context.Node[0]);
            var code        = context.AsFluent();
            var expressions = codeWriters.ToDictionary(k => k.Item1, v => new { writer = v.Item2, jumpCode = v.Item3 });

            foreach (var right in context.Node[1])
            {
                code.Push.R(Register.A);

                var @operator = right[0];
                context.Compile(right[1]);

                code.Pop.R(Register.B);

                var expr = expressions[@operator.Value];
                expr.writer(code);

                context.JumpExpression = expr.jumpCode;
            }

            return(context);
        }
Esempio n. 5
0
        private CompilerContext AssignmentExpression(CompilerContext context)
        {
            var identifier = context.Node[0];

            foreach (var right in context.Node[1])
            {
                context.Compile(right[1]);
            }

            var name   = identifier.Value;
            var symbol = context.SymbolTable[name];

            context.AsFluent()
            .Mov.RU(Register.B, symbol.Address, $"Load variable {name} into rB")
            .Add.RR(Register.B, Register.H)
            .Mov.MR(MemoryAddress.B, Register.A);

            return(context);
        }
Esempio n. 6
0
        public IEnumerable<Instruction> Compile()
        {
            var context = new CompilerContext
            {
                Code = new CodeStream(),
                Compiler = Compile,
                Node = _root,
                Parent = null,
                SymbolTable = new SymbolTable(),
            };

            foreach ( var node in context.Node )
                context.Compile(node);

            context.AsFluent()
                .Exit.R(Register.A);

            return context.Code;
        }
Esempio n. 7
0
        public IEnumerable <Instruction> Compile()
        {
            var context = new CompilerContext
            {
                Code        = new CodeStream(),
                Compiler    = Compile,
                Node        = _root,
                Parent      = null,
                SymbolTable = new SymbolTable(),
            };

            foreach (var node in context.Node)
            {
                context.Compile(node);
            }

            context.AsFluent()
            .Exit.R(Register.A);

            return(context.Code);
        }
Esempio n. 8
0
        private CompilerContext WhileStatement(CompilerContext context)
        {
            var expression = context.Node.GetNamedChild("while_condition").GetNamedChild("relational_expression");

            var conditionPtr = context.Code.Position;

            context.Compile(expression);

            var block = context.Node.GetNamedChild("block");
            var child = context.Push(block);

            var blockCode = child.Compiler(child);

            context.Code.AsFluent()
            .Je.I(blockCode.Count() + 2);

            context.Code += blockCode;
            context.Code.AsFluent()
            .Jmp.I(conditionPtr - context.Code.Position);

            return(context);
        }
Esempio n. 9
0
        private static CompilerContext CompileExpression(CompilerContext context, params Tuple<string, Action<FluentWriter>, OpCode>[] codeWriters)
        {
            context.Compile(context.Node[0]);
            var code = context.AsFluent();
            var expressions = codeWriters.ToDictionary(k => k.Item1, v => new { writer = v.Item2, jumpCode = v.Item3 });

            foreach (var right in context.Node[1])
            {
                code.Push.R(Register.A);

                var @operator = right[0];
                context.Compile(right[1]);

                code.Pop.R(Register.B);

                var expr = expressions[@operator.Value];
                expr.writer(code);

                context.JumpExpression = expr.jumpCode;
            }

            return context;
        }
Esempio n. 10
0
        private CompilerContext WhileStatement(CompilerContext context)
        {
            var expression = context.Node.GetNamedChild("while_condition").GetNamedChild("relational_expression");

            var conditionPtr = context.Code.Position;
            context.Compile(expression);

            var block = context.Node.GetNamedChild("block");
            var child = context.Push(block);

            var blockCode = child.Compiler(child);
            context.Code.AsFluent()
                .Je.I(blockCode.Count() + 2);

            context.Code += blockCode;
            context.Code.AsFluent()
                .Jmp.I(conditionPtr - context.Code.Position);

            return context;
        }
Esempio n. 11
0
        private CompilerContext Term(CompilerContext context)
        {
            var rootNode = context.Node[0];
            if ( rootNode.Is(_grammar.unary_expression) )
            {
                context.Compile(rootNode[1]);
                context.Compile(rootNode[0]);
            }
            else
            {
                context.Compile(rootNode);
            }

            return context;
        }
Esempio n. 12
0
        private CompilerContext IfStatement(CompilerContext context)
        {
            var ifFalse = Enumerable.Empty<Instruction>();

            var expression = context.Node.GetNamedChild("if_condition").GetNamedChild("relational_expression");
            context.Compile(expression);
            var jumpCode = context.JumpExpression;

            var block = context.Node.GetNamedChild("block");
            var child = context.Push(block);
            CodeStream ifTrue = child.Compiler(child);

            var elseBlock = context.Node.GetNamedChild("else_block");
            if (elseBlock != null)
            {
                block = elseBlock.GetNamedChild("block");
                child = context.Push(block);
                ifFalse = child.Compiler(child);
                ifTrue.AsFluent()
                    .Jmp.I(ifFalse.Count() + 1);
            }

            context.Code.AsFluent()
                .UnaryOp(jumpCode).I(ifTrue.Count() + 1);

            context.Code += ifTrue;
            context.Code += ifFalse;

            return context;
        }
Esempio n. 13
0
        private CodeStream Compile(CompilerContext context)
        {
            if ( context == null )
                throw new ArgumentNullException(nameof(context));

            var rule = context.Node.GetRule();
            if ( !rule.IsUnnamed() )
            {
                Func<CompilerContext, CompilerContext> codeGenerator;
                if (!_codeGenerator.TryGetValue(rule, out codeGenerator))
                    throw new InvalidOperationException("Cannot find code generator: " + rule.RuleName );

                if (codeGenerator != null)
                {
                    codeGenerator(context);
                    return context.Code;
                }
            }

            foreach ( var node in context.Node )
                context.Compile(node);

            return context.Code;
        }
Esempio n. 14
0
        private CompilerContext AssignmentExpression(CompilerContext context)
        {
            var identifier = context.Node[0];
            foreach (var right in context.Node[1])
            {
                context.Compile(right[1]);
            }

            var name = identifier.Value;
            var symbol = context.SymbolTable[name];

            context.AsFluent()
                .Mov.RU(Register.B, symbol.Address, $"Load variable {name} into rB")
                .Add.RR(Register.B, Register.H)
                .Mov.MR(MemoryAddress.B, Register.A);

            return context;
        }