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}"); } } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }