예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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, HlVarDefOperand expr)
        {
            if (expr.VariableDefinition.Modifiers.All(x => x.Type != HlTokenType.OpConstMod))
            {
                string asmVarName = expr.VariableDefinition.Name.ToString();

                if (compilation.ContainsLocalVariable(asmVarName))
                {
                    EventManager <ErrorEvent> .SendEvent(new DuplicateVarDefinitionEvent( asmVarName ));
                }

                HlTypeDefinition vdef = m_TypeSystem.GetType(
                    compilation.Root,
                    expr.VariableDefinition.TypeName.ToString()
                    );

                uint arrSize = expr.VariableDefinition.Size?.ToString().ParseUInt() ?? 1;

                if (arrSize != 1)
                {
                    vdef = new ArrayTypeDefintion(compilation.Root, vdef, arrSize);
                }

                HlExpression init = expr.Initializer.FirstOrDefault();

                if (vdef.GetSize() > 1)
                {
                    if (init is HlVarOperand vo)
                    {
                    }
                }

                compilation.CreateVariable(
                    asmVarName,
                    arrSize,
                    vdef,
                    expr.VariableDefinition.Modifiers.Any(
                        x => x.Type == HlTokenType.OpPublicMod
                        )
                                               ? VariableDataEmitFlags.Visible
                                               : VariableDataEmitFlags.None
                    );


                if (init != null)
                {
                    if (init is HlValueOperand vOp &&
                        vOp.Value.Type == HlTokenType.OpStringLiteral)
                    {
                        ExpressionTarget svar = new ExpressionTarget(
                            compilation.GetFinalName(asmVarName),
                            true,
                            vdef
                            );

                        string content = vOp.Value.ToString();

                        VariableDataEmitFlags emFlags = vdef is CStringTypeDefinition
                                                            ? VariableDataEmitFlags.CStyle
                                                            : VariableDataEmitFlags.None;

                        if (expr.VariableDefinition.Modifiers.Any(x => x.Type == HlTokenType.OpPackedMod))
                        {
                            emFlags |= VariableDataEmitFlags.Packed;
                        }

                        compilation.CreateVariable(asmVarName, content, vdef, emFlags);

                        return(new ExpressionTarget(
                                   svar.ResultAddress,
                                   true,
                                   vdef
                                   ));
                    }
                }

                ExpressionTarget dvar = new ExpressionTarget(
                    compilation.GetFinalName(asmVarName),
                    true,
                    vdef
                    );

                if (init != null)
                {
                    ExpressionTarget initVal = compilation.Parse(init, dvar);

                    ExpressionTarget initRet = initVal.CopyIfNotNull(compilation, dvar);
                    compilation.ReleaseTempVar(initVal.ResultAddress);

                    return(initRet);
                }

                return(dvar);
            }
            else
            {
                string asmVarName = expr.VariableDefinition.Name.ToString();

                if (compilation.ConstValTypes.Contains(asmVarName))
                {
                    EventManager <ErrorEvent> .SendEvent(new DuplicateConstVarDefinitionEvent( asmVarName ));
                }

                compilation.ConstValTypes.Set(
                    asmVarName,
                    new ConstantValueItem()
                {
                    Value = expr.VariableDefinition.InitializerExpression.
                            FirstOrDefault()?.
                            ToString(),
                    IsPublic = expr.VariableDefinition.Modifiers.Any(
                        x => x.Type == HlTokenType.OpPublicMod
                        ),
                    IsInternal = expr.VariableDefinition.Modifiers.Any(
                        x => x.Type == HlTokenType.OpInternalMod
                        )
                }
                    );

                return(new ExpressionTarget(
                           asmVarName,
                           true,
                           compilation.TypeSystem.GetType(
                               compilation.Root,
                               expr.VariableDefinition.TypeName.ToString()
                               )
                           ));
            }

            EventManager <ErrorEvent> .SendEvent(new DynamicVariablesNotSupportedEvent());

            return(new ExpressionTarget());
        }