Esempio n. 1
0
 private void EmitStackFunctionArgs(List <string> lines, FunctionCall functionCallNode, Context ctx)
 {
     foreach (var parameter in functionCallNode.Parameters)
     {
         if (parameter.NodeType.Body?.Count > 0)
         {
             var variable = ctx.Variables.Get((parameter as Identifier).Name);
             // var declaration = parameter as VariableDeclaration;
             var varName = TransformerHelpers.GetUID(
                 variable.VariableDeclaration.File,
                 variable.VariableDeclaration.Identifier,
                 variable.VariableDeclaration.Line,
                 variable.VariableDeclaration.Column);
             foreach (var field in parameter.NodeType.Body)
             {
                 var memoryAddress = $"fld_{varName}_{(field as VariableDeclaration).Identifier}";
                 lines.Add($"rmem reg{ctx.RegisterLevel} >{memoryAddress}");
                 lines.Add($"push reg{ctx.RegisterLevel}");
             }
         }
         else
         {
             lines.AddRange(new Transformer(new List <AstNode> {
                 parameter
             }, ctx).Transform());
             lines.Add($"push reg{ctx.RegisterLevel}");
         }
     }
 }
Esempio n. 2
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var lines  = new List <string>();
            var vdNode = node as VariableDeclaration;
            var guid   = TransformerHelpers.GetUID(vdNode.File, vdNode.Identifier, vdNode.Line, vdNode.Column);

            lines.Add($"jmp >var_{guid}_end");
            lines.Add($":var_{guid}");
            if (vdNode?.NodeType?.Body?.Count > 0)
            {
                foreach (VariableDeclaration bodyNode in vdNode.NodeType.Body)
                {
                    // lines.AddRange(Transform(bodyNode, ctx));
                    lines.Add($":fld_{guid}_{bodyNode.Identifier}");
                }
            }
            lines.Add($":var_{guid}_end");

            ctx.Variables.Add(new Variable()
            {
                Name                = vdNode.Identifier,
                MemoryAddress       = $"var_{guid}",
                VariableDeclaration = vdNode
            });

            return(lines);
        }
Esempio n. 3
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var lines         = new List <string>();
            var fcNode        = node as FunctionDeclaration;
            var name          = fcNode.Name ?? $"function_{TransformerHelpers.GetUID(fcNode.File, fcNode.Name, fcNode.Line, fcNode.Column)}";
            var memoryAddress = $"{name}";

            lines.Add($"jmp >{memoryAddress}_end");
            lines.Add($":{name}");
            ctx.Variables.Push();
            lines.AddRange(new Transformer(fcNode.Parameters, ctx).Transform());
            lines.Add("pop reg7");
            for (var index = 0; index < fcNode.Parameters.Count; index++)
            {
                var parameter = fcNode.Parameters[fcNode.Parameters.Count - index - 1];
                var variable  = ctx.Variables.Get((parameter as VariableDeclaration).Identifier);
                if (variable.VariableDeclaration.NodeType.Body?.Count > 0)
                {
                    var varName = TransformerHelpers.GetUID(
                        variable.VariableDeclaration.File,
                        variable.VariableDeclaration.Identifier,
                        variable.VariableDeclaration.Line,
                        variable.VariableDeclaration.Column);
                    for (var i = variable.VariableDeclaration.NodeType.Body.Count - 1;; i--)
                    {
                        var field        = variable.VariableDeclaration.NodeType.Body[i];
                        var fieldAddress = $"fld_{varName}_{(field as VariableDeclaration).Identifier}";
                        lines.Add($"pop reg0");
                        lines.Add($"wmem >{fieldAddress} reg0");

                        if (i == 0)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    lines.Add("pop reg0");
                    lines.Add($"wmem >{variable.MemoryAddress} reg0");
                }
            }
            lines.Add("push reg7");
            var previousRegisterLevel = ctx.RegisterLevel;

            ctx.RegisterLevel = 0;
            lines.AddRange(new Transformer(fcNode.Expression, ctx).Transform());
            ctx.RegisterLevel = previousRegisterLevel;
            lines.Add("ret");
            lines.Add($":{memoryAddress}_end");
            //Manually add variable
            lines.Add($"set reg{ctx.RegisterLevel} >{name}");
            ctx.Variables.Pop();
            return(lines);
        }
Esempio n. 4
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var lines  = new List <string>();
            var ifNode = node as If;

            var uuid = TransformerHelpers.GetUID(ifNode.File, null, ifNode.Line, ifNode.Column);

            lines.AddRange(new Transformer(ifNode.Condition, ctx).Transform());
            lines.Add($"jf reg0 >end_{uuid}");
            lines.AddRange(new Transformer(ifNode.Expression, ctx).Transform());
            lines.Add($":end_{uuid}");

            return(lines);
        }
Esempio n. 5
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var lines   = new List <string>();
            var dotNode = node as Dot;

            var variable  = ctx.Variables.Get((dotNode.Left as Identifier).Name);
            var fieldName = TransformerHelpers.GetUID(
                variable.VariableDeclaration.File,
                variable.VariableDeclaration.Identifier,
                variable.VariableDeclaration.Line,
                variable.VariableDeclaration.Column);
            var memoryAddress = $"fld_{fieldName}_{(dotNode.Right as Identifier).Name}";

            lines.Add($"rmem reg{ctx.RegisterLevel} >{memoryAddress}");

            return(lines);
        }
Esempio n. 6
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var lines  = new List <string>();
            var whNode = node as While;
            var uuid   = TransformerHelpers.GetUID(whNode.File, null, whNode.Line, whNode.Column);

            //Begin
            lines.Add($":while_{uuid}_begin");
            //Condition
            lines.AddRange(new Transformer(whNode.Condition, ctx).Transform());
            lines.Add($"jf reg0 >while_{uuid}_end");
            //Expression
            lines.AddRange(new Transformer(whNode.Expression, ctx).Transform());
            //End
            lines.Add($"jmp >while_{uuid}_begin");
            lines.Add($":while_{uuid}_end");

            return(lines);
        }
Esempio n. 7
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var lines   = new List <string>();
            var forNode = node as For;
            var uuid    = TransformerHelpers.GetUID(forNode.File, null, forNode.Line, forNode.Column);

            lines.AddRange(new Transformer(forNode.Init, ctx).Transform());
            lines.Add($":for_{uuid}_begin");
            lines.AddRange(new Transformer(forNode.Condition, ctx).Transform());
            lines.Add($"jf reg0 >for_{uuid}_end");

            lines.AddRange(new Transformer(forNode.Expression, ctx).Transform());
            lines.AddRange(new Transformer(forNode.Incrementor, ctx).Transform());

            lines.Add($"jmp >for_{uuid}_begin");
            lines.Add($":for_{uuid}_end");

            return(lines);
        }
Esempio n. 8
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var ternaryNode = node as Ternary;
            var lines       = new List <string>();

            lines.AddRange(new Transformer(new List <AstNode> {
                ternaryNode.Condition
            }, ctx).Transform());
            var negativeLabel = TransformerHelpers.GetUID(node.File, "ternary_negative", node.Line, node.Column);
            var endLabel      = TransformerHelpers.GetUID(node.File, "ternary_end", node.Line, node.Column);

            lines.Add($"jf reg0 >{negativeLabel}");
            lines.AddRange(new Transformer(new List <AstNode> {
                ternaryNode.Left
            }, ctx).Transform());
            lines.Add($"jmp >{endLabel}");
            lines.Add($":{negativeLabel}");
            lines.AddRange(new Transformer(new List <AstNode> {
                ternaryNode.Right
            }, ctx).Transform());
            lines.Add($":{endLabel}");

            return(lines);
        }
Esempio n. 9
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var pdNode              = node as PointerDeclaration;
            var lines               = new List <string>();
            var name                = pdNode.Identifier;
            var backingVarName      = $"{pdNode.Identifier}_backing";
            var backingVariableNode = new VariableDeclaration(backingVarName, pdNode.LangType.SubTypes.FirstOrDefault(), pdNode.File, pdNode.Line, pdNode.Column);

            lines.AddRange(new VariableDeclarationEmitter().Transform(backingVariableNode, ctx));

            lines.AddRange(new VariableDeclarationEmitter().Transform(pdNode, ctx));

            var backingGuid  = TransformerHelpers.GetUID(backingVariableNode.File, backingVariableNode.Identifier, backingVariableNode.Line, backingVariableNode.Column);
            var variableGuid = TransformerHelpers.GetUID(pdNode.File, pdNode.Identifier, pdNode.Line, pdNode.Column);

            lines.Add($"wmem >var_{variableGuid} >var_{backingGuid}");

            ctx.Variables.Add(new Variable
            {
                Name          = pdNode.Identifier,
                MemoryAddress = $"var_{variableGuid}"
            });
            return(lines);
        }
Esempio n. 10
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var lines  = new List <string>();
            var vaNode = node as VariableAssignment;
            // Variable variable = null;
            string memoryAddress = null;
            var    isMemoryAddressRuntimeComputed = false;

            if (vaNode.Identifier is Identifier)
            {
                var variable = ctx.Variables.Get((vaNode.Identifier as Identifier).Name);
                memoryAddress = variable.MemoryAddress;
            }
            else if (vaNode.Identifier is VariableDeclaration)
            {
                lines.AddRange(new Transformer(new List <AstNode> {
                    vaNode.Identifier
                }, ctx).Transform());
                var variable = ctx.Variables.Get((vaNode.Identifier as VariableDeclaration).Identifier);
                memoryAddress = variable.MemoryAddress;
            }
            else if (vaNode.Identifier is Dot dot)
            {
                var variable = ctx.Variables.Get((dot.Left as Identifier).Name);
                // memoryAddress = $"fld_{(dot.Left as Identifier).Name}_{(dot.Right as Identifier).Name}";
                var fieldName = TransformerHelpers.GetUID(
                    variable.VariableDeclaration.File,
                    variable.VariableDeclaration.Identifier,
                    variable.VariableDeclaration.Line,
                    variable.VariableDeclaration.Column);
                memoryAddress = $"fld_{fieldName}_{(dot.Right as Identifier).Name}";
            }

            // if (!isMemoryAddressRuntimeComputed)
            // {
            lines.AddRange(new Transformer(new List <AstNode> {
                vaNode.Parameter
            }, ctx).Transform());
            // }
            if (vaNode.Identifier is DerefArrow derefArrowNode)
            {
                var variable = ctx.Variables.Get((derefArrowNode.Left as Identifier).Name);
                var type     = variable.VariableDeclaration.NodeType.SubTypes.FirstOrDefault();
                var offset   = TypeHelper.GetFieldOffset(type, (derefArrowNode.Right as Identifier).Name);
                lines.Add($"rmem reg7 >{variable.MemoryAddress}");
                lines.Add($"add reg7 reg7 {offset}");
                // lines.Add($"rmem reg{ctx.RegisterLevel} reg{ctx.RegisterLevel}");
                isMemoryAddressRuntimeComputed = true;
            }
            var memoryAddressString = isMemoryAddressRuntimeComputed ? "reg7" : $">{memoryAddress ?? throw new Exception("Unknown memory address")}";

            // If the right-hand operand is a struct, we will do a struct copy.
            // This makes the assumption that the left-hand operand is of the same type,
            // but the type checker should enforce that
            if (vaNode.Parameter.NodeType.Body?.Count > 0)
            {
                //Translate compiletime-computed to runtime-computed so we can get offsets
                if (!isMemoryAddressRuntimeComputed)
                {
                    lines.Add($"set reg7 >{memoryAddress}");
                }
                lines.Add($"add reg7 reg7 {vaNode.Parameter.NodeType.Body.Count}");
                foreach (var _ in vaNode.Parameter.NodeType.Body)
                {
                    lines.Add($"pop reg{ctx.RegisterLevel}");
                    lines.Add($"wmem reg7 reg{ctx.RegisterLevel}");
                    lines.Add("add reg7 reg7 32767");
                }
            }
            else
            {
                lines.Add($"wmem {memoryAddressString} reg0");
            }

            return(lines);
        }
Esempio n. 11
0
        public List <string> Transform <T>(T node, Context ctx) where T : AstNode
        {
            var lines   = new List <string>();
            var strNode = node as StringLiteral;

            if (!string.IsNullOrEmpty(strNode.Value))
            {
                var emitSb = new StringBuilder();
                for (var i = 0; i < strNode.Value.Count(); i++)
                {
                    var ch = strNode.Value[i];
                    if (ch == '\\')
                    {
                        var nextChar = i + 1 < strNode.Value.Length ? strNode.Value[++i] : 0;
                        if (nextChar != 0)
                        {
                            switch (nextChar)
                            {
                            case 'n':
                                ch = Convert.ToChar("\n");
                                break;

                            case 't':
                                ch = Convert.ToChar("\t");
                                break;
                            }
                        }
                    }
                    emitSb.Append(ch);
                }
                var stringToEmit = emitSb.ToString();
                var firstLetter  = stringToEmit.Substring(0, 1);
                var value        = stringToEmit.Substring(1);
                var uuid         = TransformerHelpers.GetUID(strNode.File, null, strNode.Line, strNode.Column);
                lines.Add($"jmp >var_{uuid}_end");
                lines.Add($":var_{uuid}");
                for (var charIndex = 0; charIndex < value.Length; charIndex++)
                {
                    var ch  = value[charIndex];
                    var str = ch.ToString();
                    if (str.Trim().Count() == 0)
                    {
                        lines.Add(Encoding.ASCII.GetBytes(str).FirstOrDefault().ToString());
                    }
                    else
                    {
                        lines.Add($"&{str}");
                    }
                }
                lines.Add("0");
                lines.Add($":var_{uuid}_end");
                if (firstLetter.Trim().Count() == 0)
                {
                    lines.Add(
                        $"wmem >var_{uuid} {Encoding.ASCII.GetBytes(firstLetter).FirstOrDefault().ToString()}"
                        );
                }
                else
                {
                    lines.Add($"wmem >var_{uuid} &{firstLetter}");
                }
                lines.Add($"set reg{ctx.RegisterLevel} >var_{uuid}");
            }

            return(lines);
        }