public override ExpressionTarget ParseExpression( HlCompilation compilation, HlUnaryOp expr, ExpressionTarget outputTarget) { return(Emit(compilation, compilation.Parse(expr.Left), outputTarget)); }
protected override ExpressionTarget ComputeStatic( HlCompilation compilation, ExpressionTarget left, ExpressionTarget right) { return(new ExpressionTarget($"{left.StaticParse() * right.StaticParse()}", false, left.TypeDefinition)); }
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, 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); 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, 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); }
/// <summary> /// Registers the expression in the target container /// </summary> /// <param name="targetContainer">The target container in which the registration will be made.</param> /// <param name="expression">The expression to be registered.</param> /// <param name="declaredType">Optional. The <see cref="ITarget.DeclaredType"/> of the target to be created, /// if different from the <see cref="Expression.Type"/> of the <paramref name="expression"/> (or its /// <see cref="LambdaExpression.Body"/> if the expression is a <see cref="LambdaExpression"/>). /// /// Will also override the type against which the expression will be registered if provided.</param> /// <param name="scopeBehaviour">Optional. Controls how the object generated from the compiled expression will be /// tracked if the target is executed within an <see cref="ContainerScope" />. The default is <see cref="ScopeBehaviour.Implicit" />.</param> /// <param name="scopePreference">Optional. If <paramref name="scopeBehaviour"/> is not <see cref="ScopeBehaviour.None"/>, then this controls the /// type of scope in which the instance should be tracked. Defaults to <see cref="ScopePreference.Current"/>. <see cref="ScopePreference.Root"/> /// should be used if the result of the delegate is effectively a singleton.</param> public static void RegisterExpression( this ITargetContainer targetContainer, Expression expression, Type declaredType = null, ScopeBehaviour scopeBehaviour = ScopeBehaviour.Implicit, ScopePreference scopePreference = ScopePreference.Current) { if (targetContainer == null) { throw new ArgumentNullException(nameof(targetContainer)); } if (expression == null) { throw new ArgumentNullException(nameof(expression)); } ITarget toRegister = new ExpressionTarget(expression, declaredType); if (scopeBehaviour == ScopeBehaviour.Explicit) { toRegister = toRegister.Scoped(); } else if (scopeBehaviour == ScopeBehaviour.None) { toRegister = toRegister.Unscoped(); } targetContainer.Register(toRegister); }
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 target = compilation.Parse(expr.Left); HlTypeDefinition tDef = target.TypeDefinition ?? compilation.TypeSystem.GetType(compilation.Root, HLBaseTypeNames.s_UintTypeName); string funcName = tDef.GetFinalStaticFunction(expr.OperationType.ToString()); return(InvocationExpressionCompiler.ParseFunctionInvocation( compilation, new HlInvocationOp( new HlValueOperand( new HlTextToken( HlTokenType.OpWord, funcName, 0 ) ), new[] { expr.Left } ), 1, funcName, "JSR" )); }
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 void DeclaredTypeShouldBeInheritedFromLambdaExpression() { Expression <Func <ResolveContext, string> > expr = c => "hello world"; var result2 = new ExpressionTarget(expr); Assert.Same(typeof(string), result2.DeclaredType); }
public void DeclaredTypeShouldBeInheritedFromConstantExpression() { //use two expressions: a lambda and a standard expression var expr = Expression.Constant("hello world"); var result1 = new ExpressionTarget(expr); Assert.Same(typeof(string), result1.DeclaredType); }
private bool IsReducable(ExpressionTarget target) { if (!target.IsAddress) { uint v = target.StaticParse(); return(v != 0 && (v & (v - 1)) == 0); //Is Power of 2? } return(false); }
private void ParseBody(HlCompilation compilation, HlWhileOp expr, string start, string end) { foreach (HlExpression hlExpression in expr.Block) { ExpressionTarget e = compilation.Parse(hlExpression); compilation.ReleaseTempVar(e.ResultAddress); } compilation.EmitterResult.Emit($"JMP", start); compilation.EmitterResult.Store($".{end} linker:hide"); }
public void ShouldSetExpressionOrFactory() { var expr = Expression.Constant("hello world"); Assert.Same(expr, new ExpressionTarget(expr).Expression); Func <ICompileContext, Expression> factory = c => expr; var factoryTarget = new ExpressionTarget(factory, typeof(string)); //we test DeclaredType for straight Expressions next Assert.Same(factory, factoryTarget.ExpressionFactory); Assert.Equal(typeof(string), factoryTarget.DeclaredType); }
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 static ExpressionTarget Emit( HlCompilation compilation, ExpressionTarget target, ExpressionTarget outputTarget) { compilation.EmitterResult.Emit( $"LOAD", outputTarget.ResultAddress, target.ResultAddress ); return(outputTarget.Cast(target.TypeDefinition)); }
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, HlUnaryOp expr) { ExpressionTarget target = compilation.Parse(expr.Left); string instrKey = target.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName ? "INC.F" : "INC"; compilation.EmitterResult.Emit( instrKey, target.ResultAddress ); return(target); }
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, HlValueOperand expr, ExpressionTarget outputTarget) { string type; string value; switch (expr.Value.Type) { case HlTokenType.OpCharLiteral: type = HLBaseTypeNames.s_UintTypeName; value = $"'{expr.Value}'"; break; case HlTokenType.OpDecimalNumber: type = HLBaseTypeNames.s_FloatTypeName; unsafe { float val = float.Parse(expr.Value.ToString()); value = (*( uint * )&val).ToString(); } break; default: type = HLBaseTypeNames.s_UintTypeName; value = expr.Value.ToString(); break; } compilation.EmitterResult.Emit($"LOAD", outputTarget.ResultAddress, value); return(outputTarget.Cast(compilation.TypeSystem.GetType(compilation.Root, type))); }
public ExpressionTarget Compile(HlCompilation compilation, HlInvocationOp expr) { ExpressionTarget t = compilation.Parse(expr.ParameterList.First()); ExpressionTarget ret = ReferenceExpressionCompiler.Emit( compilation, t, new ExpressionTarget( SettingsManager.GetSettings <HlCompilerSettings>().OmitTempVarInit ? compilation.GetTempVar() : compilation.GetTempVar(0), true, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) ) ); compilation.ReleaseTempVar(t.ResultAddress); return(ret); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlUnaryOp expr) { ExpressionTarget target = compilation.Parse(expr.Left); string instrKey = target.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName ? "DEC.F" : "DEC"; ExpressionTarget copy = new ExpressionTarget( compilation.GetTempVarCopy(target.ResultAddress), target.IsAddress, target.TypeDefinition, target.IsPointer ); compilation.EmitterResult.Emit( //Decrement Original and pass decremented copy instrKey, target.ResultAddress ); compilation.ReleaseTempVar(target.ResultAddress); return(copy); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlValueOperand expr) { string type; string value; switch (expr.Value.Type) { case HlTokenType.OpCharLiteral: type = HLBaseTypeNames.s_UintTypeName; value = $"'{expr.Value}'"; break; case HlTokenType.OpDecimalNumber: type = HLBaseTypeNames.s_FloatTypeName; unsafe { float val = float.Parse(expr.Value.ToString()); value = (*( uint * )&val).ToString(); } break; default: type = HLBaseTypeNames.s_UintTypeName; value = expr.Value.ToString(); break; } ExpressionTarget tmp = new ExpressionTarget(value, false, compilation.TypeSystem.GetType(compilation.Root, type)); return(tmp); }
public override uint StaticEvaluate(ExpressionTarget a, ExpressionTarget b) { return(a.StaticParse() > b.StaticParse() ? 1U : 0U); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlVarOperand expr, ExpressionTarget outputTarget) { if (compilation.ConstValTypes.Contains(expr.Value.ToString())) { return(new ExpressionTarget( expr.Value.ToString(), true, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) ). CopyIfNotNull(compilation, outputTarget)); } string varAddr; if (compilation.ContainsVariable(expr.Value.ToString())) { VariableData v = compilation.GetVariable(expr.Value.ToString()); varAddr = v.GetFinalName(); return(new ExpressionTarget( varAddr, true, v.TypeDefinition, !v.TypeDefinition.IsValueType || v.IsPointer ).CopyIfNotNull(compilation, outputTarget)); } if (compilation.FunctionMap.Contains(expr.Value.ToString())) { varAddr = expr.Value.ToString(); return(new ExpressionTarget(varAddr, true, null)); } if (compilation.TypeSystem.HasType(compilation.Root, expr.Value.ToString())) { HlTypeDefinition tdef = compilation.TypeSystem.GetType(compilation.Root, expr.Value.ToString()); return(new ExpressionTarget("%%TYPE%%", false, tdef, false)); } if (compilation.ExternalSymbols.Any(x => x.GetName() == expr.Value.ToString())) { return(new ExpressionTarget( compilation.ExternalSymbols. First(x => x.GetName() == expr.Value.ToString()). GetFinalName(), false, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ) )); } EventManager <ErrorEvent> .SendEvent(new HlVariableNotFoundEvent( expr.Value.ToString(), false )); return(new ExpressionTarget()); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlMemberAccessOp expr, ExpressionTarget outputTarget) { string tmpVar; ExpressionTarget lType = compilation.Parse(expr.Left); if (lType.ResultAddress == "%%TYPE%%") { if (expr.MemberName is HlInvocationOp invoc) { HlMemberDefinition data = null; bool writeProlog = invoc.Left.ToString() == "new"; if (invoc.Left.ToString() == "new" || invoc.Left.ToString() == "base") { data = lType.TypeDefinition.StaticConstructor; } else { data = lType.TypeDefinition.GetPrivateOrPublicMember(invoc.Left.ToString()); } if (lType.TypeDefinition.IsAbstract && writeProlog && data == lType.TypeDefinition.StaticConstructor) { EventManager <ErrorEvent> .SendEvent( new AbstractConstructorCallEvent( lType.TypeDefinition ) ); } if (data != null && !data.IsStatic) { EventManager <WarningEvent> .SendEvent( new StaticInstanceMemberAccessEvent( lType.TypeDefinition, data ) ); } invoc.Redirect(null, lType.TypeDefinition, data, writeProlog); ExpressionTarget t = compilation.Parse(invoc, outputTarget). CopyIfNotNull(compilation, outputTarget); return(t); } else { HlMemberDefinition data = lType.TypeDefinition.GetPrivateOrPublicMember(expr.MemberName.ToString()); string funcName = lType.TypeDefinition. GetFinalMemberName(data); //$"FUN_{lType.TypeDefinition.Name}_{expr.MemberName}"; if (data.IsStatic && data is HlPropertyDefinition propDef) { funcName = compilation.GetFinalName(funcName); } if (!data.IsStatic) { EventManager <WarningEvent> .SendEvent( new StaticInstanceMemberAccessEvent( lType.TypeDefinition, data ) ); } if (outputTarget.ResultAddress != null) { compilation.EmitterResult.Emit("LOAD", funcName, outputTarget.ResultAddress); return(outputTarget); } return(new ExpressionTarget( funcName, true, compilation.TypeSystem.GetType( compilation.Root, HLBaseTypeNames.s_UintTypeName ), false )); } } string containerName = expr.MemberName.ToString(); if (expr.MemberName is HlInvocationOp inv) { if (lType.TypeDefinition.HasMember(inv.Left.ToString()) && lType.TypeDefinition.GetPrivateOrPublicMember(inv.Left.ToString()) is HlPropertyDefinition) { containerName = inv.Left.ToString(); } else { HlMemberDefinition data = lType.TypeDefinition.GetPrivateOrPublicMember(inv.Left.ToString()); inv.Redirect( lType.ResultAddress, lType.TypeDefinition, data ); ExpressionTarget tVal = compilation.Parse(inv, outputTarget); ExpressionTarget t = tVal.CopyIfNotNull(compilation, outputTarget); return(t); } } else if (expr.MemberName is HlArrayAccessorOp arr && lType.TypeDefinition.GetPrivateOrPublicMember(arr.Left.ToString()) is HlPropertyDefinition) { containerName = arr.Left.ToString(); } uint off = HlTypeDefinition.RecursiveGetOffset( lType.TypeDefinition, 0, 0, containerName.Split('.') ); string tmpOff = compilation.GetTempVar(off); if (lType.IsPointer) { tmpVar = compilation.GetTempVarCopy(lType.ResultAddress); } else { tmpVar = compilation.GetTempVarLoad(lType.ResultAddress); } compilation.EmitterResult.Emit($"ADD", tmpVar, tmpOff); compilation.ReleaseTempVar(tmpOff); HlMemberDefinition mdef = null; if (expr.Left.ToString() == "this") { mdef = HlTypeDefinition.RecursiveGetPrivateOrPublicMember( lType.TypeDefinition, 0, containerName.Split('.') ); } else { mdef = HlTypeDefinition.RecursiveGetPublicMember( lType.TypeDefinition, 0, containerName.Split('.') ); } if (mdef is HlPropertyDefinition pdef) { if (outputTarget.ResultAddress != null) { compilation.EmitterResult.Emit($"DREF", tmpVar, outputTarget.ResultAddress); compilation.ReleaseTempVar(tmpVar); return(outputTarget); } return(new ExpressionTarget(tmpVar, true, pdef.PropertyType, true)); } if (mdef is HlFunctionDefinition fdef) { if (outputTarget.ResultAddress != null) { compilation.EmitterResult.Emit($"DREF", tmpVar, outputTarget.ResultAddress); compilation.ReleaseTempVar(tmpVar); return(outputTarget); } return(new ExpressionTarget(tmpVar, true, fdef.ReturnType, true)); } 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); }