Example #1
0
        private bool TryLookupType(string typeName, out TypeInfo typeInfo)
        {
            if (BuiltInPrimitives.TryGetValue(typeName, out typeInfo))
            {
                return(true);
            }

            return(userDefinedTypes.TryGetValue(typeName, out typeInfo));
        }
Example #2
0
        private string EvaluateOperator(Operator op, string varName)
        {
            bool isSpecialVar = SpecialVariables.AllSpecialVariables.Contains(varName);
            bool isLocalVar   = TryLookupLocal(varName, out double localVarVal);

            // Handle special variables
            if (isSpecialVar)
            {
                if (op != Operator.ValueOf)
                {
                    Log(LogLevel.Warning, "Operator {0} cannot be used on special variable '{1}'.", op, varName);
                    return("");
                }

                switch (varName)
                {
                case SpecialVariables.Filesize:
                    return(file.Length + "");

                case SpecialVariables.GlobalOffset:
                    return(GlobalOffset + "");

                case SpecialVariables.Offset:
                    return(CurrentCodeBlock.Offset + "");
                }
            }

            // Handle local variables
            if (isLocalVar)
            {
                if (op != Operator.ValueOf)
                {
                    Log(LogLevel.Warning, "Operator {0} cannot be used on local variable '{1}'.", op, varName);
                    return("");
                }

                return(localVarVal + "");
            }

            bool isVar             = CurrentCodeBlock.Symbol.TryLookup(varName, out SymbolTable sym);
            bool isUserDefinedType = userDefinedTypes.TryGetValue(varName, out TypeInfo usrType);
            bool isBuiltinType     = BuiltInPrimitives.TryGetValue(varName, out TypeInfo builtinType);

            if (!(isVar || isUserDefinedType || isBuiltinType))
            {
                // TODO: get statement. Perhaps throw a different exception and have Caller of ResolveVariables catch and handle it
                string msg = "Unknown variable or typename '{0}'";
                throw LayoutScriptException.Create <LayoutScriptException>(layout, null, msg, varName);
            }

            string val = "";

            switch (op)
            {
            case Operator.GlobalOffsetOf:
                if (CurrentCodeBlock.IsProcessingTypedef)
                {
                    string msg = "GlobalOffsetOf operator not valid within type definitions.";
                    throw LayoutScriptException.Create <LayoutScriptException>(layout, null, msg, varName);
                }

                if (isVar)
                {
                    val = sym.GlobalDataAddress.ToString();
                }
                else
                {
                    string msg = "GlobalOffsetOf operator not valid for types.";
                    throw LayoutScriptException.Create <LayoutScriptException>(layout, null, msg, varName);
                }
                break;

            case Operator.OffsetOf:
                if (CurrentCodeBlock.IsProcessingTypedef)
                {
                    string msg = "OffsetOf operator not valid within type definitions.";
                    throw LayoutScriptException.Create <LayoutScriptException>(layout, null, msg, varName);
                }

                if (isVar)
                {
                    val = sym.LocalDataAddress.ToString();
                }
                else
                {
                    string msg = "OffsetOf operator not valid for types.";
                    throw LayoutScriptException.Create <LayoutScriptException>(layout, null, msg, varName);
                }
                break;

            case Operator.SizeOf:
                if (isVar)
                {
                    val = sym.DataLength.ToString();
                }
                else if (isBuiltinType)
                {
                    val = builtinType.Size.ToString();
                }
                else if (isUserDefinedType)
                {
                    val = usrType.Size.ToString();
                }
                break;

            case Operator.ValueOf:
                if (CurrentCodeBlock.IsProcessingTypedef)
                {
                    string msg = "ValueOf operator not valid within type definitions.";
                    throw LayoutScriptException.Create <LayoutScriptException>(layout, null, msg, varName);
                }

                if (isVar)
                {
                    val = StringValueOf(sym);
                }
                else
                {
                    string msg = "ValueOf operator not valid for types.";
                    throw LayoutScriptException.Create <LayoutScriptException>(layout, null, msg, varName);
                }
                break;
            }

            return(val);
        }