public override void Compile(Assembly assembly, Scope scope, Register target) { var reg = scope.FindAndUseFreeRegister(); (ChildNodes[0] as CompilableNode).Compile(assembly, scope, (Register)reg); if (reg != (int)Register.A) assembly.Add("SET", "A", Scope.GetRegisterLabelSecond(reg)); scope.FreeMaybeRegister(reg); if (reg == (int)Register.STACK) scope.stackDepth -= 1; if (scope.activeFunction != null) scope.activeFunction.CompileReturn(assembly, scope); else assembly.Add("BRK", "", ""); }
public override void Compile(Assembly assembly, Scope scope, Register target) { var destRegister = target == Register.STACK ? scope.FindAndUseFreeRegister() : (int)target; (ChildNodes[0] as CompilableNode).Compile(assembly, scope, (Register)destRegister); if (target == Register.STACK) { if (destRegister == (int)Register.STACK) assembly.Add("SET", "PEEK", "[PEEK]"); else { assembly.Add("SET", "PUSH", "[" + Scope.GetRegisterLabelSecond(destRegister) + "]"); scope.stackDepth += 1; scope.FreeMaybeRegister(destRegister); } } else { assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), "[" + Scope.GetRegisterLabelSecond(destRegister) + "]"); if (destRegister == (int)Register.STACK) scope.stackDepth -= 1; else if (destRegister != (int)target) scope.FreeMaybeRegister(destRegister); } }
public override void Compile(Assembly assembly, Scope scope, Register target) { int secondTarget = (int)Register.STACK; var secondConstant = (ChildNodes[1] as CompilableNode).IsConstant(); var firstConstant = (ChildNodes[0] as CompilableNode).IsConstant(); if (firstConstant && secondConstant) { assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), hex(GetConstantValue())); if (target == Register.STACK) scope.stackDepth += 1; return; } if (!secondConstant) { secondTarget = scope.FindAndUseFreeRegister(); (ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)secondTarget); } if (!firstConstant) (ChildNodes[0] as CompilableNode).Compile(assembly, scope, target); if (target == Register.STACK) { assembly.Add("SET", Scope.TempRegister, firstConstant ? hex((ChildNodes[0] as CompilableNode).GetConstantValue()) : "POP"); assembly.Add(opcodes[AsString], Scope.TempRegister, secondConstant ? hex((ChildNodes[1] as CompilableNode).GetConstantValue()) : Scope.GetRegisterLabelSecond(secondTarget)); assembly.Add("SET", "PUSH", Scope.TempRegister); } else { if (firstConstant) assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), hex((ChildNodes[0] as CompilableNode).GetConstantValue())); assembly.Add(opcodes[AsString], Scope.GetRegisterLabelFirst((int)target), secondConstant ? hex((ChildNodes[1] as CompilableNode).GetConstantValue()) : Scope.GetRegisterLabelSecond(secondTarget)); } if (secondTarget == (int)Register.STACK && !secondConstant) scope.stackDepth -= 1; else scope.FreeMaybeRegister(secondTarget); }
public static ClauseOrder CompileConditional(Assembly assembly, Scope scope, CompilableNode conditionNode) { if (!(conditionNode is ComparisonNode)) { var condTarget = scope.FindAndUseFreeRegister(); conditionNode.Compile(assembly, scope, (Register)condTarget); assembly.Add("IFE", Scope.GetRegisterLabelSecond(condTarget), "0x0", "If from expression"); scope.FreeMaybeRegister(condTarget); return ClauseOrder.PassFirst; } else { var op = conditionNode.AsString; ushort firstConstantValue = 0, secondConstantValue = 0; var firstIsConstant = (conditionNode.ChildNodes[0] as CompilableNode).IsConstant(); var secondIsConstant = (conditionNode.ChildNodes[1] as CompilableNode).IsConstant(); int firstRegister = (int)Register.STACK; int secondRegister = (int)Register.STACK; if (secondIsConstant) secondConstantValue = (conditionNode.ChildNodes[1] as CompilableNode).GetConstantValue(); else { secondRegister = scope.FindAndUseFreeRegister(); (conditionNode.ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)secondRegister); } if (firstIsConstant) firstConstantValue = (conditionNode.ChildNodes[0] as CompilableNode).GetConstantValue(); else { firstRegister = scope.FindAndUseFreeRegister(); (conditionNode.ChildNodes[0] as CompilableNode).Compile(assembly, scope, (Register)firstRegister); } if (op == "==") { if (firstIsConstant && secondIsConstant) { if (firstConstantValue == secondConstantValue) { return ClauseOrder.ConstantPass; } else { return ClauseOrder.ConstantFail; } } else if (firstIsConstant) { assembly.Add("IFE", (conditionNode.ChildNodes[0] as CompilableNode).GetConstantToken(), Scope.GetRegisterLabelSecond(secondRegister)); releaseRegister(scope, secondRegister); return ClauseOrder.FailFirst; } else if (secondIsConstant) { assembly.Add("IFE", Scope.GetRegisterLabelSecond(firstRegister), hex(secondConstantValue)); releaseRegister(scope, firstRegister); return ClauseOrder.FailFirst; } else { assembly.Add("IFE", Scope.GetRegisterLabelSecond(firstRegister), Scope.GetRegisterLabelSecond(secondRegister)); releaseRegister(scope, firstRegister); releaseRegister(scope, secondRegister); return ClauseOrder.FailFirst; } } else if (op == "!=") { if (firstIsConstant && secondIsConstant) { if (firstConstantValue != secondConstantValue) { return ClauseOrder.ConstantPass; } else { return ClauseOrder.ConstantFail; } } else if (firstIsConstant) { assembly.Add("IFN", hex(firstConstantValue), Scope.GetRegisterLabelSecond(secondRegister)); releaseRegister(scope, secondRegister); return ClauseOrder.FailFirst; } else if (secondIsConstant) { assembly.Add("IFN", Scope.GetRegisterLabelSecond(firstRegister), hex(secondConstantValue)); releaseRegister(scope, firstRegister); return ClauseOrder.FailFirst; } else { assembly.Add("IFN", Scope.GetRegisterLabelSecond(firstRegister), Scope.GetRegisterLabelSecond(secondRegister)); releaseRegister(scope, firstRegister); releaseRegister(scope, secondRegister); return ClauseOrder.FailFirst; } } else if (op == ">") { if (firstIsConstant && secondIsConstant) { if (firstConstantValue > secondConstantValue) { return ClauseOrder.ConstantPass; } else { return ClauseOrder.ConstantFail; } } else if (firstIsConstant) { assembly.Add("IFG", hex(firstConstantValue), Scope.GetRegisterLabelSecond(secondRegister)); releaseRegister(scope, secondRegister); return ClauseOrder.FailFirst; } else if (secondIsConstant) { assembly.Add("IFG", Scope.GetRegisterLabelSecond(firstRegister), hex(secondConstantValue)); releaseRegister(scope, firstRegister); return ClauseOrder.FailFirst; } else { assembly.Add("IFG", Scope.GetRegisterLabelSecond(firstRegister), Scope.GetRegisterLabelSecond(secondRegister)); releaseRegister(scope, firstRegister); releaseRegister(scope, secondRegister); return ClauseOrder.FailFirst; } } } throw new CompileError("Impossible situation reached"); }
private static void releaseRegister(Scope scope, int reg) { scope.FreeMaybeRegister(reg); if (reg == (int)Register.STACK) scope.stackDepth -= 1; }
public override void Compile(Assembly assembly, Scope scope, Register target) { if (ChildNodes[0] is VariableNameNode) { var variable = scope.FindVariable(ChildNodes[0].AsString); if (variable == null) throw new CompileError("Could not find variable " + ChildNodes[0].AsString); if (variable.location == Register.STACK) { var register = scope.FindAndUseFreeRegister(); (ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)register); scope.FreeMaybeRegister(register); if (scope.stackDepth - variable.stackOffset > 1) { assembly.Add("SET", Scope.TempRegister, "SP"); assembly.Add("SET", "[" + hex(scope.stackDepth - variable.stackOffset - 1) + "+" + Scope.TempRegister + "]", Scope.GetRegisterLabelSecond(register), "Fetching variable"); } else assembly.Add("SET", "PEEK", Scope.GetRegisterLabelSecond(register), "Fetching variable"); if (register == (int)Register.STACK) scope.stackDepth -= 1; } else if (variable.location == Register.STATIC) { //if (!variable.emitBrackets) throw new CompileError("Can't assign to data pointers!"); var register = scope.FindAndUseFreeRegister(); (ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)register); scope.FreeMaybeRegister(register); assembly.Add("SET", "[" + variable.staticLabel + "]", Scope.GetRegisterLabelSecond(register)); if (register == (int)Register.STACK) scope.stackDepth -= 1; } else if (variable.location == Register.CONST) { throw new CompileError("Can't assign to const"); } else (ChildNodes[1] as CompilableNode).Compile(assembly, scope, variable.location); } else if (ChildNodes[0] is DereferenceNode) { bool firstConstant = false; int firstRegister = (int)Register.STACK; if ((ChildNodes[0].ChildNodes[0] as CompilableNode).IsConstant()) firstConstant = true; else { firstRegister = scope.FindAndUseFreeRegister(); (ChildNodes[0].ChildNodes[0] as CompilableNode).Compile(assembly, scope, (Register)firstRegister); } var secondRegister = scope.FindAndUseFreeRegister(); (ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)secondRegister); if (firstConstant) { assembly.Add("SET", "[" + hex((ChildNodes[0].ChildNodes[0] as CompilableNode).GetConstantValue()) + "]", Scope.GetRegisterLabelSecond(secondRegister)); if (secondRegister == (int)Register.STACK) scope.stackDepth -= 1; else scope.FreeMaybeRegister(secondRegister); } else { if (firstRegister == (int)Register.STACK && secondRegister == (int)Register.STACK) { assembly.Add("SET", Scope.TempRegister, "POP"); assembly.Add("SET", "[" + Scope.TempRegister + "]", "POP"); scope.stackDepth -= 2; } else if (secondRegister == (int)Register.STACK) { assembly.Add("SET", "[" + Scope.GetRegisterLabelFirst(firstRegister) + "]", "POP"); scope.stackDepth -= 1; scope.FreeMaybeRegister(firstRegister); return; } else if (firstRegister == (int)Register.STACK) { throw new CompileError("Impossible situation entered"); } else { assembly.Add("SET", "[" + Scope.GetRegisterLabelFirst(firstRegister) + "]", Scope.GetRegisterLabelSecond(secondRegister)); scope.FreeMaybeRegister(firstRegister); scope.FreeMaybeRegister(secondRegister); } } } }