public static ExpressionTarget ParseFunctionInvocation( HlCompilation compilation, HlInvocationOp expr, int targetLength, string functionName, string jumpInstruction) { if (expr.ParameterList.Length != targetLength) { if (!(expr.MemberDefinition != null && (expr.MemberDefinition == expr.InstanceType.StaticConstructor || expr.MemberDefinition == expr.InstanceType.DynamicConstructor || expr.Instance == null))) { EventManager <ErrorEvent> .SendEvent( new FunctionArgumentMismatchEvent( $"{functionName}: Invalid parameter Count. Expected {targetLength} got {expr.ParameterList.Length}" ) ); } } if (expr.Instance != null) { compilation.EmitterResult.Emit( $"PUSH", expr.Instance ); } foreach (HlExpression parameter in expr.ParameterList) { ExpressionTarget argVal = compilation.Parse( parameter ); ExpressionTarget arg = argVal.MakeAddress(compilation); compilation.EmitterResult.Emit( $"PUSH", arg.ResultAddress ); compilation.ReleaseTempVar(arg.ResultAddress); compilation.ReleaseTempVar(argVal.ResultAddress); } compilation.EmitterResult.Emit(jumpInstruction, functionName); ExpressionTarget tempReturn = new ExpressionTarget( compilation.GetTempVarPop(), true, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) ); return(tempReturn); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlReturnOp expr) { if (expr.Right != null) { ExpressionTarget ptVal = compilation.Parse( expr.Right ); ExpressionTarget pt = ptVal. MakeAddress(compilation); compilation.EmitterResult.Emit($"PUSH", pt.ResultAddress); compilation.ReleaseTempVar(pt.ResultAddress); compilation.ReleaseTempVar(ptVal.ResultAddress); } else { string v = SettingsManager.GetSettings <HlCompilerSettings>().OmitTempVarInit ? compilation.GetTempVar() : compilation.GetTempVar(0); compilation.EmitterResult.Emit($"PUSH", v); compilation.ReleaseTempVar(v); } compilation.EmitterResult.Emit("RET"); return(new ExpressionTarget()); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlUnaryOp expr, ExpressionTarget outputTarget) { ExpressionTarget targetVal = compilation.Parse( expr.Left ); ExpressionTarget target = targetVal.MakeAddress(compilation); if (target.TypeDefinition.Name != HLBaseTypeNames.s_FloatTypeName) { EventManager <WarningEvent> .SendEvent( new UnaryMinusExpressionInvalidEvent( "Unary inversion is only possible with signed types and floats, performing this instruction on other types may yield undefined results." ) ); } if (outputTarget.ResultAddress == target.ResultAddress) { compilation.EmitterResult.Emit("INV.F", outputTarget.ResultAddress); return(outputTarget); } else { compilation.EmitterResult.Emit("INV.F", target.ResultAddress, outputTarget.ResultAddress); ExpressionTarget ret = target.CopyIfNotNull(compilation, outputTarget); compilation.ReleaseTempVar(target.ResultAddress); return(ret); } }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlArrayAccessorOp expr, ExpressionTarget outputTarget) { ExpressionTarget tempPtrVar = compilation.Parse(expr.Left); ExpressionTarget tempPtr = new ExpressionTarget( SettingsManager.GetSettings <HlCompilerSettings>().OmitTempVarInit ? compilation.GetTempVar() : compilation.GetTempVar(0), true, tempPtrVar.TypeDefinition, true ); ExpressionTarget pnVal = compilation.Parse( expr.ParameterList[0] ); ExpressionTarget pn = pnVal.MakeAddress(compilation); if (tempPtrVar.TypeDefinition is ArrayTypeDefintion adef) { string tmpSName = compilation.GetTempVar(adef.ElementType.GetSize()); compilation.EmitterResult.Emit($"MUL", pn.ResultAddress, tmpSName); compilation.ReleaseTempVar(tmpSName); compilation.EmitterResult.Emit($"LOAD", tempPtr.ResultAddress, tempPtrVar.ResultAddress); } else { string tmpSName = compilation.GetTempVar(tempPtrVar.TypeDefinition.GetSize()); compilation.EmitterResult.Emit($"MUL", pn.ResultAddress, tmpSName); compilation.ReleaseTempVar(tmpSName); compilation.EmitterResult.Emit($"COPY", tempPtrVar.ResultAddress, tempPtr.ResultAddress); } compilation.EmitterResult.Emit($"ADD", tempPtr.ResultAddress, pn.ResultAddress); if (outputTarget.ResultAddress != null) { compilation.EmitterResult.Emit( $"DREF", tempPtr.ResultAddress, outputTarget.ResultAddress ); compilation.ReleaseTempVar(tempPtr.ResultAddress); compilation.ReleaseTempVar(tempPtrVar.ResultAddress); compilation.ReleaseTempVar(pn.ResultAddress); compilation.ReleaseTempVar(pnVal.ResultAddress); return(outputTarget); } compilation.ReleaseTempVar(tempPtrVar.ResultAddress); compilation.ReleaseTempVar(pn.ResultAddress); compilation.ReleaseTempVar(pnVal.ResultAddress); return(tempPtr); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlUnaryOp expr, ExpressionTarget outputTarget) { ExpressionTarget targetVal = compilation.Parse( expr.Left ); ExpressionTarget target = targetVal. MakeAddress(compilation); //BNE target rTarget if_b0_fail //LOAD possibleTarget 0x1; True Value //.if_b0_fail string label = HlCompilation.GetUniqueName("bexpr_not"); compilation.EmitterResult.Emit($"LOAD", outputTarget.ResultAddress, "1"); compilation.EmitterResult.Emit($"BEZ", target.ResultAddress, label); compilation.EmitterResult.Emit($"LOAD", outputTarget.ResultAddress, "0"); compilation.EmitterResult.Store($".{label} linker:hide"); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); return(outputTarget); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlBinaryOp expr) { ExpressionTarget target = compilation.Parse(expr.Left); ExpressionTarget rTargetVal = compilation.Parse( expr.Right ); ExpressionTarget rTarget = rTargetVal.MakeAddress(compilation); string instrKey = target.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName || rTarget.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName ? InstructionKey + ".F" : InstructionKey; compilation.EmitterResult.Emit( instrKey, target.ResultAddress, rTarget.ResultAddress ); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(target); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlForOp expr) { string startLabel = HlCompilation.GetUniqueName("for_start"); string condLabel = HlCompilation.GetUniqueName("for_eval_condition"); string endLabel = HlCompilation.GetUniqueName("for_end"); HlCompilation subFor = new HlCompilation(compilation, HlCompilation.GetUniqueName("for")); subFor.EmitterResult.Store( $".{startLabel} linker:hide" ); //Unused, makes clear where the for compiler started emitting code. ExpressionTarget targetVal = subFor.Parse(expr.VDecl); ExpressionTarget target = targetVal.MakeAddress(subFor); //Declare Variable(left) subFor.EmitterResult.Store($".{condLabel} linker:hide"); //Label to jumpto ExpressionTarget condVal = subFor.Parse(expr.Condition); //Check Condition ExpressionTarget cond = condVal.MakeAddress(subFor); //Check Condition subFor.EmitterResult.Emit( $"BEZ", cond.ResultAddress, endLabel ); //Check if Expression "Equal to Zero" => jump to end if it is foreach (HlExpression hlExpression in expr.ExprBody) { subFor.ReleaseTempVar( subFor.Parse(hlExpression). ResultAddress ); //Parse block and clean up any temp variables that were emitted. } subFor.ReleaseTempVar(subFor.Parse(expr.VInc).ResultAddress); //Compute Increment Expression subFor.EmitterResult.Emit($"JMP", condLabel); //Jump back up if we executed the body. subFor.EmitterResult.Store( $".{endLabel} linker:hide" ); //End label that we jump to if we exit the loop subFor.ReleaseTempVar(target.ResultAddress); subFor.ReleaseTempVar(targetVal.ResultAddress); subFor.ReleaseTempVar(cond.ResultAddress); subFor.ReleaseTempVar(condVal.ResultAddress); compilation.EmitterResult.Store(subFor.EmitVariables(false)); compilation.EmitterResult.Store(subFor.EmitterResult.Get()); return(new ExpressionTarget()); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlBinaryOp expr) { ExpressionTarget target = compilation.Parse(expr.Left); ExpressionTarget rTarget = compilation.Parse( expr.Right ); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeReduceExpressions&& IsReducable(rTarget)) { uint amount = GetPowLevel(rTarget.StaticParse()); string tmp = compilation.GetTempVarLoad(amount.ToString()); ExpressionTarget taddr = target.MakeAddress(compilation); compilation.EmitterResult.Emit( "SHR", taddr.ResultAddress, tmp ); compilation.ReleaseTempVar(tmp); compilation.ReleaseTempVar(taddr.ResultAddress); return(target); } string rtOrig = rTarget.ResultAddress; rTarget = rTarget.MakeAddress(compilation); string instrKey = target.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName || rTarget.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName ? InstructionKey + ".F" : InstructionKey; compilation.EmitterResult.Emit( instrKey, target.ResultAddress, rTarget.ResultAddress ); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(rtOrig); return(target); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlWhileOp expr) { string startLabel = HlCompilation.GetUniqueName("while_start"); string endLabel = HlCompilation.GetUniqueName("while_end"); HlCompilation whileComp = new HlCompilation(compilation, HlCompilation.GetUniqueName("while")); whileComp.EmitterResult.Store($".{startLabel} linker:hide"); ExpressionTarget targetVal = whileComp.Parse(expr.Condition); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeWhileConditionExpressions&& !targetVal.IsAddress) { if (targetVal.StaticParse() != 0) //If True we parse body without check and directly jump to condition //If False we omit the whole loop entirely { ParseBody(whileComp, expr, startLabel, endLabel); } compilation.EmitterResult.Store(whileComp.EmitVariables(false)); compilation.EmitterResult.Store(whileComp.EmitterResult.Get()); return(new ExpressionTarget()); } ExpressionTarget target = targetVal.MakeAddress(whileComp); //Make sure we have an address and not a static value whileComp.EmitterResult.Emit($"BEZ", target.ResultAddress, endLabel); ParseBody(whileComp, expr, startLabel, endLabel); whileComp.ReleaseTempVar(target.ResultAddress); whileComp.ReleaseTempVar(targetVal.ResultAddress); compilation.EmitterResult.Store(whileComp.EmitVariables(false)); compilation.EmitterResult.Store(whileComp.EmitterResult.Get()); //.while_start //LOAD tmp_condition_var 0x00 //<PARSE CONDITION EXPR HERE> //BEZ tmp_condition_var while_end //<PARSE BLOCK HERE> //JMP while_start //.while_end return(new ExpressionTarget()); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlBinaryOp expr, ExpressionTarget outputTarget) { ExpressionTarget target = compilation.Parse(expr.Left); ExpressionTarget rTargetVal = compilation.Parse( expr.Left ); ExpressionTarget rTarget = rTargetVal. MakeAddress(compilation); if (target.ResultAddress == outputTarget.ResultAddress) { compilation.EmitterResult.Emit( $"XOR", target.ResultAddress, rTarget.ResultAddress ); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); } else { compilation.EmitterResult.Emit( $"XOR", target.ResultAddress, rTarget.ResultAddress, outputTarget.ResultAddress ); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); } return(target); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlUnaryOp expr, ExpressionTarget outputTarget) { ExpressionTarget targetVal = compilation.Parse( expr.Left ); ExpressionTarget target = targetVal. MakeAddress(compilation); string tmp = compilation.GetTempVar(~( uint )0); compilation.EmitterResult.Emit($"XOR", target.ResultAddress, tmp); ExpressionTarget ret = target.CopyIfNotNull(compilation, outputTarget); compilation.ReleaseTempVar(tmp); compilation.ReleaseTempVar(target.ResultAddress); return(ret); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlIfOp expr) { string endLabel = HlCompilation.GetUniqueName("if_end"); string elseLabel = HlCompilation.GetUniqueName("if_else"); string blockLabels = HlCompilation.GetUniqueName("if_b{0}"); bool staticComputation = false; compilation.EmitterResult.Store("; Start IF"); for (int i = 0; i < expr.ConditionMap.Count; i++) { string thisLabel = string.Format(blockLabels, i); HlCompilation subIf = new HlCompilation(compilation, HlCompilation.GetUniqueName(thisLabel)); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeIfConditionExpressions&& expr.ConditionMap[i].Item1.IsStatic()) { ExpressionTarget t = subIf.Parse( expr.ConditionMap[i].Item1 ); if (t.StaticParse() != 0) { staticComputation = true; foreach (HlExpression hlExpression in expr.ConditionMap[i].Item2) { ExpressionTarget e = subIf.Parse(hlExpression); compilation.ReleaseTempVar(e.ResultAddress); } compilation.EmitterResult.Store(subIf.EmitVariables(false)); compilation.EmitterResult.Store(subIf.EmitterResult.Get()); break; } if (i != 0) { subIf.EmitterResult.Store($".{thisLabel} linker:hide"); } continue; } if (i != 0) { subIf.EmitterResult.Store($".{thisLabel} linker:hide"); } ExpressionTarget exprTargetVal = subIf.Parse( expr.ConditionMap[i].Item1 ); ExpressionTarget exprTarget = exprTargetVal.MakeAddress(subIf); string nextLabel; if (i < expr.ConditionMap.Count - 1) { nextLabel = string.Format(blockLabels, i + 1); } else { nextLabel = expr.ElseBranch != null ? elseLabel : endLabel; } subIf.EmitterResult.Emit($"BEZ", exprTarget.ResultAddress, nextLabel); foreach (HlExpression hlExpression in expr.ConditionMap[i].Item2) { ExpressionTarget e = subIf.Parse(hlExpression); compilation.ReleaseTempVar(e.ResultAddress); } subIf.EmitterResult.Emit($"JMP", endLabel); subIf.ReleaseTempVar(exprTarget.ResultAddress); subIf.ReleaseTempVar(exprTargetVal.ResultAddress); compilation.EmitterResult.Store(subIf.EmitVariables(false)); compilation.EmitterResult.Store(subIf.EmitterResult.Get()); } if (!staticComputation && expr.ElseBranch != null) { HlCompilation subIf = new HlCompilation(compilation, elseLabel); subIf.EmitterResult.Store($".{elseLabel} linker:hide"); foreach (HlExpression hlExpression in expr.ElseBranch) { ExpressionTarget e = subIf.Parse(hlExpression); compilation.ReleaseTempVar(e.ResultAddress); } compilation.EmitterResult.Store(subIf.EmitVariables(false)); compilation.EmitterResult.Store(subIf.EmitterResult.Get()); } compilation.EmitterResult.Store($".{endLabel} linker:hide"); return(new ExpressionTarget()); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlBinaryOp expr, ExpressionTarget outputTarget) { ExpressionTarget targetVal = compilation.Parse( expr.Left ); ExpressionTarget rTargetVal = compilation.Parse( expr.Right ); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeConstExpressions&& !targetVal.IsAddress && !rTargetVal.IsAddress) { return(new ExpressionTarget( StaticEvaluate(targetVal, rTargetVal).ToString(), false, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) )); } ExpressionTarget target = targetVal.MakeAddress(compilation); ExpressionTarget rTarget = rTargetVal.MakeAddress(compilation); if (target.IsPointer) { ExpressionTarget tmp = new ExpressionTarget( compilation.GetTempVarDref(target.ResultAddress), true, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) ); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); target = tmp; } if (rTarget.IsPointer) { ExpressionTarget tmp = new ExpressionTarget( compilation.GetTempVarDref(rTarget.ResultAddress), true, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) ); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); rTarget = tmp; } //BNE target rTarget if_b0_fail //LOAD possibleTarget 0x1; True Value //.if_b0_fail string label = HlCompilation.GetUniqueName("rel_expr_comp"); compilation.EmitterResult.Emit($"LOAD", outputTarget.ResultAddress, "1"); compilation.EmitterResult.Store( $"{InstructionKey} {target.ResultAddress} {rTarget.ResultAddress} {label}" ); compilation.EmitterResult.Emit($"LOAD", outputTarget.ResultAddress, "0"); compilation.EmitterResult.Store($".{label} linker:hide"); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlBinaryOp expr, ExpressionTarget outputTarget) { ExpressionTarget targetVal = compilation.Parse(expr.Left); ExpressionTarget rTargetVal = compilation.Parse(expr.Right); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeConstExpressions&& !targetVal.IsAddress && !rTargetVal.IsAddress) { return(ComputeStatic(compilation, targetVal, rTargetVal)); } if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeConstExpressions) { uint amount = 0; ExpressionTarget baseExpr = default; if (IsReducable(targetVal)) { baseExpr = rTargetVal.MakeAddress(compilation); amount = GetPowLevel(targetVal.StaticParse()); } else if (IsReducable(rTargetVal)) { baseExpr = targetVal.MakeAddress(compilation); amount = GetPowLevel(rTargetVal.StaticParse()); } if (amount != 0) { string tmp = compilation.GetTempVarLoad(amount.ToString()); compilation.EmitterResult.Emit( "SHL", baseExpr.ResultAddress, tmp, outputTarget.ResultAddress ); compilation.ReleaseTempVar(tmp); compilation.ReleaseTempVar(baseExpr.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); } } ExpressionTarget target = targetVal.MakeAddress(compilation); ExpressionTarget rTarget = rTargetVal.MakeAddress(compilation); string instrKey = target.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName || rTarget.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName ? InstructionKey + ".F" : InstructionKey; if (target.IsPointer) { ExpressionTarget et = new ExpressionTarget( compilation.GetTempVarDref(target.ResultAddress), true, target.TypeDefinition ); compilation.EmitterResult.Emit( instrKey, et.ResultAddress, rTarget.ResultAddress, outputTarget.ResultAddress ); compilation.ReleaseTempVar(et.ResultAddress); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); } compilation.EmitterResult.Emit( instrKey, target.ResultAddress, rTarget.ResultAddress, outputTarget.ResultAddress ); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlInvocationOp expr) { string target = expr.Left.ToString(); if (m_CtFuncCollection.IsCompiletimeFunction(target)) { return(m_CtFuncCollection.Compile(target, compilation, expr)); } bool isInternalFunc = compilation.FunctionMap.Contains(target); IExternalData externalSymbol = compilation.ExternalSymbols.FirstOrDefault( x => x.GetName() == target && x.DataType == ExternalDataType.Function ); //if (expr.Instance == null && // expr.MemberDefinition == null && // expr.InstanceType != null && // target == "new") //{ // ExpressionTarget instance = compilation.Parse(expr.ParameterList[0]); // HlTypeDefinition tdef = expr.InstanceType; // ExpressionTarget ret = new ExpressionTarget( // instance.ResultAddress, // true, // tdef, // true // ); // if(SettingsManager.GetSettings<HlCompilerSettings>().ConstructorPrologMode == HlTypeConstructorPrologMode.Outline) // WriteConstructorInvocationProlog(compilation, tdef, ret.ResultAddress); // return ret; //} if (expr.Instance == null && expr.InstanceType != null) { if (expr.MemberDefinition == expr.InstanceType.StaticConstructor) { ExpressionTarget instance = compilation.Parse(expr.ParameterList[0]); HlTypeDefinition tdef = expr.InstanceType; ExpressionTarget ret = new ExpressionTarget( instance.ResultAddress, true, tdef, true ); if (expr.WriteProlog && SettingsManager.GetSettings <HlCompilerSettings>().ConstructorPrologMode == HlTypeConstructorPrologMode.Outline) { WriteConstructorInvocationProlog(compilation, tdef, ret.ResultAddress); } expr.Redirect(ret.ResultAddress, tdef, tdef.StaticConstructor, expr.WriteProlog); ParseExpression( compilation, expr ); return(ret); } else { int l = (expr.MemberDefinition as HlFunctionDefinition).ParameterTypes.Length; if (isInternalFunc) { compilation.FunctionMap.Get(target).SetUsed(); } else { externalSymbol?.SetUsed(); } return(ParseFunctionInvocation(compilation, expr, l, target, "JSR")); } } if (compilation.TypeSystem.HasType(compilation.Root, target)) { string var = HlCompilation.GetUniqueName("static_alloc"); HlTypeDefinition tdef = compilation.TypeSystem.GetType(compilation.Root, target); uint size = tdef.GetSize(); compilation.CreateVariable(var, size, tdef, VariableDataEmitFlags.None); string finalName = compilation.GetFinalName(var); ExpressionTarget ret = new ExpressionTarget( compilation.GetTempVarLoad(finalName), true, tdef, true ); if (SettingsManager.GetSettings <HlCompilerSettings>().ConstructorPrologMode == HlTypeConstructorPrologMode.Outline) { WriteConstructorInvocationProlog(compilation, tdef, ret.ResultAddress); } if (tdef.StaticConstructor != null) { expr.Redirect(ret.ResultAddress, tdef, tdef.StaticConstructor); ParseExpression( compilation, expr ); } return(ret); } if (expr.Instance != null && expr.MemberDefinition is HlFunctionDefinition fdef) { if (fdef.IsVirtual || fdef.IsAbstract || fdef.IsOverride) { uint i = expr.InstanceType.GetOffset(fdef.Name); string init = i.ToString(); string tmp = compilation.GetTempVarLoad(init); compilation.EmitterResult.Emit("ADD", tmp, expr.Instance); compilation.EmitterResult.Emit("DREF", tmp, tmp); int targetLength = fdef.ParameterTypes != null ? fdef.ParameterTypes.Length : expr.ParameterList.Length; externalSymbol?.SetUsed(); ExpressionTarget t = ParseFunctionInvocation(compilation, expr, targetLength, tmp, "JSREF"); compilation.ReleaseTempVar(tmp); return(t); } else if (!isInternalFunc && externalSymbol == null) { string funcEmit = target; int targetLength = fdef.ParameterTypes?.Length ?? expr.ParameterList.Length; if (expr.InstanceType != null && expr.InstanceType.StaticConstructor == expr.MemberDefinition && expr.WriteProlog && SettingsManager.GetSettings <HlCompilerSettings>().ConstructorPrologMode == HlTypeConstructorPrologMode.Inline) { funcEmit = expr.InstanceType.GetInternalConstructor(compilation); } return(ParseFunctionInvocation(compilation, expr, targetLength, funcEmit, "JSR")); } } if (isInternalFunc) { string funcEmit = target; FunctionData fData = compilation.FunctionMap.Get(target); int targetLength = fData.ParameterCount; //if (!expr.WriteProlog && SettingsManager.GetSettings < HlCompilerSettings >().ConstructorPrologMode == // HlTypeConstructorPrologMode.Inline ) //{ // funcEmit = expr.MemberDefinition. //} if (expr.InstanceType != null && expr.InstanceType.StaticConstructor == expr.MemberDefinition && expr.WriteProlog && SettingsManager.GetSettings <HlCompilerSettings>().ConstructorPrologMode == HlTypeConstructorPrologMode.Inline) { funcEmit = expr.InstanceType.GetInternalConstructor(compilation); } fData.SetUsed(); return(ParseFunctionInvocation(compilation, expr, targetLength, funcEmit, "JSR"). Cast( compilation.TypeSystem.GetType( compilation.Root, fData?.ReturnType ?? HLBaseTypeNames.s_UintTypeName ) )); } if (externalSymbol != null) { string funcEmit = (externalSymbol as LinkedData)?.Info.Address.ToString() ?? target; FunctionData fData = externalSymbol as FunctionData; int targetLength = (externalSymbol as FunctionData)?.ParameterCount ?? expr.ParameterList.Length; if (expr.InstanceType != null && expr.InstanceType.StaticConstructor == expr.MemberDefinition && expr.WriteProlog && SettingsManager.GetSettings <HlCompilerSettings>().ConstructorPrologMode == HlTypeConstructorPrologMode.Inline) { funcEmit = expr.InstanceType.GetInternalConstructor(compilation); } externalSymbol.SetUsed(); return(ParseFunctionInvocation(compilation, expr, targetLength, funcEmit, "JSR"). Cast(compilation.TypeSystem.GetType( compilation.Root, fData?.ReturnType ?? HLBaseTypeNames.s_UintTypeName ))); } //if (isInternalFunc || externalSymbol != null) //{ // string funcEmit = externalSymbol is LinkedData l ? l.Info.Address.ToString() : target; // int targetLength = isInternalFunc // ? compilation.FunctionMap.Get(target).ParameterCount // : (externalSymbol as FunctionData)?.ParameterCount ?? // expr.ParameterList.Length; // //if (!expr.WriteProlog && SettingsManager.GetSettings < HlCompilerSettings >().ConstructorPrologMode == // // HlTypeConstructorPrologMode.Inline ) // //{ // // funcEmit = expr.MemberDefinition. // //} // return ParseFunctionInvocation(compilation, expr, targetLength, funcEmit, "JSR"); //} if (compilation.ContainsVariable(target) || compilation.ConstValTypes.Contains(target)) { foreach (HlExpression parameter in expr.ParameterList) { ExpressionTarget ttVal = compilation.Parse(parameter); ExpressionTarget tt = ttVal.MakeAddress(compilation); compilation.EmitterResult.Emit( $"PUSH", tt.ResultAddress ); compilation.ReleaseTempVar(tt.ResultAddress); compilation.ReleaseTempVar(ttVal.ResultAddress); } if (compilation.ContainsVariable(target)) { compilation.EmitterResult.Emit($"JSREF", compilation.GetFinalName(target)); } else { compilation.EmitterResult.Emit($"JSREF", target); } ExpressionTarget tempReturn = new ExpressionTarget( compilation.GetTempVarPop(), true, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) ); return(tempReturn); } EventManager <ErrorEvent> .SendEvent(new FunctionNotFoundEvent( target )); return(new ExpressionTarget()); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlBinaryOp expr, ExpressionTarget outputTarget) { ExpressionTarget targetVal = compilation.Parse( expr.Left ); ExpressionTarget rTargetVal = compilation.Parse(expr.Right); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeConstExpressions&& !targetVal.IsAddress && !rTargetVal.IsAddress && targetVal.TypeDefinition.Name == HLBaseTypeNames.s_UintTypeName && rTargetVal.TypeDefinition.Name == HLBaseTypeNames.s_UintTypeName) { return(ComputeStatic(compilation, targetVal, rTargetVal)); } ExpressionTarget target = targetVal.MakeAddress(compilation); ExpressionTarget rTarget = rTargetVal.MakeAddress(compilation); string instrKey = target.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName || rTarget.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName ? InstructionKey + ".F" : InstructionKey; if (target.IsPointer) { ExpressionTarget et = new ExpressionTarget( compilation.GetTempVarDref(target.ResultAddress), true, target.TypeDefinition ); compilation.EmitterResult.Emit( instrKey, et.ResultAddress, rTarget.ResultAddress, outputTarget.ResultAddress ); compilation.ReleaseTempVar(et.ResultAddress); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); } if (target.ResultAddress == outputTarget.ResultAddress) { compilation.EmitterResult.Emit( instrKey, target.ResultAddress, rTarget.ResultAddress ); } else { compilation.EmitterResult.Emit( instrKey, target.ResultAddress, rTarget.ResultAddress, outputTarget.ResultAddress ); } compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlBinaryOp expr) { ExpressionTarget targetVal = compilation.Parse( expr.Left ); ExpressionTarget target = targetVal. MakeAddress(compilation); ExpressionTarget rTargetVal = compilation.Parse( expr.Right, !target.IsPointer ? target : default ); ExpressionTarget rTarget = rTargetVal. MakeAddress(compilation); if (rTarget.ResultAddress == target.ResultAddress) { return(target); } if (!rTarget.IsAddress && !target.IsPointer) { compilation.EmitterResult.Emit( $"LOAD", target.ResultAddress, rTarget.ResultAddress ); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(target); } if (target.IsPointer) { if (rTarget.IsPointer) { compilation.EmitterResult.Emit( $"CREF", rTarget.ResultAddress, target.ResultAddress ); } else { ExpressionTarget tmpTarget = new ExpressionTarget( compilation.GetTempVarLoad( rTarget.ResultAddress ), true, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) ); compilation.EmitterResult.Emit( $"CREF", tmpTarget.ResultAddress, target.ResultAddress ); compilation.ReleaseTempVar(tmpTarget.ResultAddress); } } else { if (rTarget.IsPointer) { ExpressionTarget tmpTarget = new ExpressionTarget( compilation.GetTempVarLoad( target.ResultAddress ), true, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) ); compilation.EmitterResult.Emit( $"CREF", rTarget.ResultAddress, tmpTarget.ResultAddress ); compilation.ReleaseTempVar(tmpTarget.ResultAddress); } else if (rTarget.ResultAddress != target.ResultAddress) { compilation.EmitterResult.Emit( $"COPY", rTarget.ResultAddress, target.ResultAddress ); } } compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(target); }