Example #1
0
        List <object> CreateSymbols(List <TokenExpression> tokens, bool GenerateAdditionalFunctions)
        {
            List <object> declarationOrder = new List <object>();

            var classDefinitions     = tokens.TokensWhere(TokenType.ClassDefinition).ToArray();
            var functypeDeclarations = tokens.TokensWhere(TokenType.FunctypeDeclaration).ToArray();

            //var globalDefinitions = tokens.TokensWhere(TokenType.VariableDeclaration);
            //var constDefinitions = tokens.TokensWhere(TokenType.ConstDeclaration);
            //var functionDeclarations = tokens.TokensWhere(TokenType.FunctionDeclaration);

            //create structs
            foreach (var token in classDefinitions)
            {
                string className  = token.Subexpressions[1].Token.Value;
                var    structInfo = Structs.Get(className);
                declarationOrder.Add(structInfo);
            }

            //create function/delegate
            foreach (var token in functypeDeclarations)
            {
                var    functionNameToken = token.Subexpressions[2];
                string funcTypeName      = GetFunctionName(functionNameToken, null);
                if (token.Subexpressions[0].TokenType == TokenType.Delegate)
                {
                    var delegateInfo = Delegates.Get(funcTypeName);
                    declarationOrder.Add(delegateInfo);
                }
                else
                {
                    var functype = Functypes.Get(funcTypeName);
                    declarationOrder.Add(functype);
                }
            }

            //data types exist now - now create structs, functions, functypes, globals, constants

            foreach (var token in tokens)
            {
                switch (token.TokenType)
                {
                case TokenType.ClassDefinition:
                {
                    string className  = token.Subexpressions[1].Token.Value;
                    var    structInfo = this.Structs.Get(className);

                    HashSet <string> memberNames = new HashSet <string>();
                    memberNames.AddRange(structInfo.Members.Names());

                    var entries = token.Subexpressions[2].Subexpressions;
                    foreach (var entry0 in entries)
                    {
                        var entry = entry0.Subexpressions[0];
                        switch (entry.TokenType)
                        {
                        case TokenType.FunctionDeclaration:
                        {
                            Function function;
                            var      blockToken = entry0.GetFirstSubexpression(TokenType.Block);
                            if (blockToken != null)
                            {
                                //create function, and add it to the list (gives it an index)
                                function = CreateSymbolForFunction(entry, className, true);
                                this.FunctionDefinitionTokens[function] = blockToken;
                                declarationOrder.Add(function);
                            }
                            else
                            {
                                //declaration without a definition - don't add it to the list until it's actually defined
                                function = CreateSymbolForFunction(entry, className, false);
                            }
                            var  functionParameterList = entry.GetFirstSubexpression(TokenType.FunctionParameterList);
                            bool hasAssignment         = (functionParameterList.GetSubexpressionsRecursive(TokenType.Assign).FirstOrDefault() != null);
                            if (hasAssignment)
                            {
                                this.FunctionDeclarationTokens[function] = entry;
                            }
                        }
                        break;

                        case TokenType.ConstDeclaration:
                        {
                            CreateSymbolForConst(entry, className);
                        }
                        break;

                        case TokenType.VariableDeclaration:
                        {
                            var variables = GetVariablesInVariableDeclaration(entry);
                            foreach (var variable in variables)
                            {
                                //does symbol already exist?
                                if (variable.DataType != DataType.Void && memberNames.Contains(variable.Name))
                                {
                                    //do nothing
                                }
                                else
                                {
                                    int index = structInfo.Members.Count;
                                    structInfo.Members.Add(variable);
                                    variable.Index  = index;
                                    variable.Parent = structInfo;
                                    variable.Root   = ainFile;

                                    memberNames.Add(variable.Name);
                                }
                            }
                        }
                        break;
                        }
                    }
                }
                break;

                case TokenType.FunctypeDeclaration:
                {
                    var declarationToken   = token.Subexpressions[0];
                    var dataTypeToken      = token.Subexpressions[1];
                    var functionNameToken  = token.Subexpressions[2];
                    var parameterListToken = token.Subexpressions[3];

                    var    dataType     = GetDataType(dataTypeToken);
                    string functypeName = GetFunctionName(functionNameToken);

                    FunctionType funcType;
                    if (declarationToken.TokenType == TokenType.Delegate)
                    {
                        funcType = Delegates.Get(functypeName);
                    }
                    else
                    {
                        funcType = Functypes.Get(functypeName);
                    }
                    funcType.SetVariableType(dataType);

                    int parameterNumber = 0;
                    foreach (var parameterDataTypeToken in parameterListToken.Subexpressions)
                    {
                        int index     = funcType.Parameters.Count;
                        var parameter = GetDataType(parameterDataTypeToken);
                        if (parameter.DataType != DataType.Void)
                        {
                            parameter.Name  = parameterNumber.ToString();
                            parameter.Index = index;
                            parameter.Root  = ainFile;
                            funcType.Parameters.Add(parameter);
                            if (parameter.DataType.IsPrimitiveRefType())
                            {
                                var voidParameter = new Variable("<void>", DataType.Void, 0, 0);
                                voidParameter.Index = index + 1;
                                voidParameter.Root  = ainFile;
                                funcType.Parameters.Add(voidParameter);
                            }
                        }
                        parameterNumber++;
                    }
                    funcType.ParameterCount = funcType.Parameters.Count;
                }
                break;

                case TokenType.FunctionDeclaration:
                {
                    var function = CreateSymbolForFunction(token);
                    declarationOrder.Add(function);
                    var blockToken = token.GetFirstSubexpression(TokenType.Block);
                    if (blockToken != null)
                    {
                        this.FunctionDefinitionTokens[function] = blockToken;
                    }
                    var  functionParameterList = token.GetFirstSubexpression(TokenType.FunctionParameterList);
                    bool hasAssignment         = (functionParameterList.GetSubexpressionsRecursive(TokenType.Assign).FirstOrDefault() != null);
                    if (hasAssignment)
                    {
                        this.FunctionDeclarationTokens[function] = token;
                    }
                }
                break;

                case TokenType.GlobalGroupDeclaration:
                {
                    var    groupNameToken = token.Subexpressions.FirstOrDefault();
                    string groupName      = groupNameToken.Token.Value;
                    int    groupIndex     = this.GlobalGroupNames.Add(groupName);

                    foreach (var variableDeclarationToken in token.Subexpressions.TokensWhere(TokenType.VariableDeclaration))
                    {
                        var variables = GetVariablesInVariableDeclaration(variableDeclarationToken);
                        foreach (var variable in variables)
                        {
                            if (variable.Name == "<void>")
                            {
                                var global = new Global();
                                global.GroupIndex = groupIndex;
                                global.Name       = variable.Name;
                                global.SetVariableType(variable);
                                global.Index = Globals.List.Count;
                                global.Root  = ainFile;
                                Globals.List.Add(global);
                            }
                            else
                            {
                                var global = Globals.Get(variable.Name);
                                if (this.ArraySizeExpressions.ContainsKey(variable))
                                {
                                    this.ArraySizeExpressions[global] = this.ArraySizeExpressions[variable];
                                }
                                global.SetVariableType(variable);
                                global.GroupIndex = groupIndex;
                                declarationOrder.Add(global);
                            }
                        }
                    }
                }
                break;

                case TokenType.VariableDeclaration:
                {
                    var variables = GetVariablesInVariableDeclaration(token);
                    foreach (var variable in variables)
                    {
                        if (variable.Name == "<void>")
                        {
                            var global = new Global();
                            global.Name = variable.Name;
                            global.SetVariableType(variable);
                            global.Index = Globals.List.Count;
                            global.Root  = ainFile;
                            Globals.List.Add(global);
                        }
                        else
                        {
                            var global = Globals.Get(variable.Name);
                            declarationOrder.Add(global);
                            if (this.ArraySizeExpressions.ContainsKey(variable))
                            {
                                this.ArraySizeExpressions[global] = this.ArraySizeExpressions[variable];
                            }
                            global.SetVariableType(variable);
                        }
                    }
                }
                break;

                case TokenType.ConstDeclaration:
                {
                    CreateSymbolForConst(token);
                }
                break;

                case TokenType.Eof:
                {
                    string fileName = token.Subexpressions[0].Token.Value;
                    declarationOrder.Add(fileName);
                }
                break;

                case TokenType.HllDeclaration:
                {
                    string libraryName = token.Subexpressions[0].Token.Value;
                    CreateHllSymbols(token.Subexpressions, libraryName, libraryName);
                    declarationOrder.Add(Libraries.Get(libraryName));
                }
                break;
                }
            }
            Function zeroFunction       = null;
            bool     createZeroFunction = false;

            if (GenerateAdditionalFunctions)
            {
                createZeroFunction = !Functions.Contains("0");
                zeroFunction       = null;

                if (createZeroFunction)
                {
                    zeroFunction = Functions.Get("0", false);
                    declarationOrder.Add(zeroFunction);
                }
            }

            var declaraedStructs = declarationOrder.OfType <Struct>().OrderByIndex().ToArray();

            foreach (var sturctInfo in declaraedStructs)
            {
                GenerateArrayInitializer(declarationOrder, sturctInfo, true, false);
            }

            if (GenerateAdditionalFunctions)
            {
                //create @2 functions for each constructor
                foreach (var structInfo in Structs.List)
                {
                    GenerateArrayInitializer(declarationOrder, structInfo, false, false);
                }

                if (createZeroFunction)
                {
                    //create 0 function
                    zeroFunction = Functions.Get("0");

                    //wait until later to define it
                }

                this.FunctionDefinitionTokens[Functions.Get("NULL")] = new TokenExpression(TokenType.Block);
                declarationOrder.Add(ainFile.GetFunction("NULL"));
            }

            return(declarationOrder);
        }
Example #2
0
        internal Variable GetDataType(TokenExpression dataTypeToken)
        {
            bool     isRef           = false;
            bool     isArray         = false;
            int      structType      = -1;
            int      arrayDimensions = 0;
            DataType dataType        = DataType.Void;

            for (int i = 0; i < dataTypeToken.Subexpressions.Count; i++)
            {
                var token = dataTypeToken.Subexpressions[i];

                switch (token.TokenType)
                {
                case TokenType.ArrayType:
                    dataTypeToken = token;
                    i             = -1;
                    continue;

                case TokenType.Ref:
                    isRef = true;
                    break;

                case TokenType.Array:
                    isArray = true;
                    //i++;
                    arrayDimensions = 1;
                    break;

                case TokenType.Number:
                    arrayDimensions = token.Token.ToInt();
                    break;

                case TokenType.Void:
                    dataType = DataType.Void;
                    break;

                case TokenType.Int:
                    dataType = DataType.Int;
                    if (isArray)
                    {
                        dataType += 4;
                    }
                    if (isRef)
                    {
                        dataType += 8;
                    }
                    break;

                case TokenType.Struct:
                    dataType   = DataType.Struct;
                    structType = -1;
                    if (isArray)
                    {
                        dataType += 4;
                    }
                    if (isRef)
                    {
                        dataType += 8;
                    }
                    break;

                case TokenType.String:
                    dataType = DataType.String;
                    if (isArray)
                    {
                        dataType += 4;
                    }
                    if (isRef)
                    {
                        dataType += 8;
                    }
                    break;

                case TokenType.Float:
                    dataType = DataType.Float;
                    if (isArray)
                    {
                        dataType += 4;
                    }
                    if (isRef)
                    {
                        dataType += 8;
                    }
                    break;

                case TokenType.Bool:
                    dataType = DataType.Bool;
                    if (isArray && !isRef)
                    {
                        dataType += 3;
                    }
                    else if (!isArray && isRef)
                    {
                        dataType += 4;
                    }
                    else if (isArray && isRef)
                    {
                        dataType += 5;
                    }
                    break;

                case TokenType.Lint:
                    dataType = DataType.Lint;
                    if (isArray && !isRef)
                    {
                        dataType += 3;
                    }
                    else if (!isArray && isRef)
                    {
                        dataType += 4;
                    }
                    else if (isArray && isRef)
                    {
                        dataType += 5;
                    }
                    break;

                case TokenType.IMainSystem:
                    dataType = DataType.IMainSystem;
                    break;

                case TokenType.Identifier:
                    string name = token.Token.Value;
                    if (Structs.Contains(name))
                    {
                        structType = Structs.NameToIndex[name];
                        dataType   = DataType.Struct;
                        if (isArray)
                        {
                            dataType += 4;
                        }
                        if (isRef)
                        {
                            dataType += 8;
                        }
                    }
                    else if (Functypes.Contains(name))
                    {
                        structType = Functypes.NameToIndex[name];
                        dataType   = DataType.Functype;
                        if (isArray && !isRef)
                        {
                            dataType += 3;
                        }
                        else if (!isArray && isRef)
                        {
                            dataType += 4;
                        }
                        else if (isArray && isRef)
                        {
                            dataType += 5;
                        }
                    }
                    else if (Delegates.Contains(name))
                    {
                        structType = Delegates.NameToIndex[name];
                        dataType   = DataType.Delegate;
                        if (isArray && !isRef)
                        {
                            dataType += 3;
                        }
                        else if (!isArray && isRef)
                        {
                            dataType += 4;
                        }
                        else if (isArray && isRef)
                        {
                            dataType += 5;
                        }
                    }
                    else
                    {
                        //HLL data types
                        if (name == "intp")
                        {
                            dataType = DataType.RefInt;
                        }
                        else if (name == "stringp")
                        {
                            dataType = DataType.RefString;
                        }
                        else if (name == "floatp")
                        {
                            dataType = DataType.RefFloat;
                        }
                        else if (name == "boolp")
                        {
                            dataType = DataType.RefBool;
                        }
                        else
                        {
                            //unknown data type
                            dataType = DataType.Struct;
                            if (isRef)
                            {
                                dataType = DataType.RefStruct;
                            }
                            structType = -1;
                        }
                    }
                    break;
                }
            }
            return(new Variable("", dataType, structType, arrayDimensions));
        }