Beispiel #1
0
        private void GenerateArrayInitializer(List <object> declarationOrder, Struct structInfo, bool forceOverwrite, bool createIfUnnecessary)
        {
            string constructorName = structInfo.Name + "@0";

            if (Functions.Contains(constructorName))
            {
                var    function                 = Functions.Get(constructorName);
                string arrayInitializerName     = structInfo.Name + "@2";
                bool   anyMembersHaveArraySizes = AnyMembersHaveArraySizes(structInfo);

                //if (((anyMembersHaveArraySizes && ainFile.Version >= 6) || (ainFile.Version < 6)) &&
                //    (forceOverwrite || !Functions.Contains(arrayInitializerName)))
                if (anyMembersHaveArraySizes || createIfUnnecessary)
                {
                    var arrayInitializer = Functions.Get(arrayInitializerName);
                    declarationOrder.Add(arrayInitializer);
                    TokenExpression block = new TokenExpression(TokenType.Block);
                    foreach (var member in structInfo.Members)
                    {
                        if (member.DataType.IsNonRefArray() && this.ArraySizeExpressions.ContainsKey(member))
                        {
                            AddArrayDeclarationToBlock(block, member);
                        }
                    }

                    this.FunctionDefinitionTokens[arrayInitializer] = block;
                }
            }
        }
        public TokenExpression Clone()
        {
            var clone = new TokenExpression(Token.Clone());

            clone.Subexpressions = this.Subexpressions.Clone(clone);
            clone.TokenType      = this.TokenType;
            return(clone);
        }
Beispiel #3
0
        private Function CreateSymbolForFunction(TokenExpression functionDeclarationToken, string className, bool createSymbol)
        {
            var      dataTypeToken = functionDeclarationToken.GetFirstSubexpression(TokenType.DataType);
            Variable dataType;

            if (dataTypeToken != null)
            {
                dataType = GetDataType(dataTypeToken);
            }
            else
            {
                dataType = new Variable("", DataType.Void, -1, 0);
            }
            var    functionNameToken = functionDeclarationToken.GetFirstSubexpression(TokenType.FunctionName);
            string functionName      = GetFunctionName(functionNameToken, className);

            var function = Functions.Get(functionName, createSymbol);

            function.SetVariableType(dataType);
            if (function.Parameters != null && function.Parameters.Count > 0)
            {
                function.Parameters.Clear();
            }


            var poundSignToken = functionDeclarationToken.GetFirstSubexpression(TokenType.Pound);

            if (poundSignToken != null)
            {
                function.IsLabel = 1;
            }


            //add parameters
            var functionParameterListToken = functionDeclarationToken.GetFirstSubexpression(TokenType.FunctionParameterList);

            if (functionParameterListToken != null)
            {
                var parameters = GetVariablesInFunctionParameters(functionParameterListToken);

                if (function.Parameters.Count < parameters.Length)
                {
                    function.Parameters.Clear();
                    foreach (var parameter in parameters)
                    {
                        int index = function.Parameters.Count;
                        parameter.Root   = ainFile;
                        parameter.Parent = function;
                        parameter.Index  = index;
                        function.Parameters.Add(parameter);
                    }
                    function.ParameterCount = function.Parameters.Count;
                }
            }

            return(function);
        }
Beispiel #4
0
 private void RaiseError2(string errorMessage, TokenExpression tokenExpression)
 {
     errorMessage += ": ";
     if (tokenExpression != null)
     {
         errorMessage += tokenExpression.ToStringReal();
     }
     RaiseError(errorMessage, tokenExpression);
 }
Beispiel #5
0
        private void RaiseError(string errorMessage, TokenExpression tokenExpression)
        {
            int    row = -1, column = -1;
            string fileName     = null;
            string functionName = null;

            if (currentFunction != null)
            {
                functionName = currentFunction.Name;
            }
            if (tokenExpression != null)
            {
                row          = tokenExpression.Row;
                column       = tokenExpression.Column;
                fileName     = tokenExpression.FileName;
                errorMessage = "Line " + (row + 1).ToString() + ", column " + (column + 1).ToString() + ": " + errorMessage;
            }
            else
            {
                fileName = lastErrorFilename;
            }
            if (Error != null)
            {
                if (fileName != lastErrorFilename)
                {
                    string errorMessage1 = "In file: " + fileName;
                    if (fileName != null)
                    {
                        Error(this, new ErrorEventArgs(new Exception(errorMessage1)));
                    }
                }
                lastErrorFilename = fileName;
                if (functionName != lastErrorFunctionName)
                {
                    string errorMessage1 = "In function: " + functionName;
                    if (functionName != null)
                    {
                        Error(this, new ErrorEventArgs(new Exception(errorMessage1)));
                    }
                }
                lastErrorFunctionName = functionName;
                Error(this, new ErrorEventArgs(new Exception(errorMessage)));
            }
            Debug.WriteLine(errorMessage + "\n\t" + tokenExpression.FileName + " @" + tokenExpression.row);
            Errors.Add(errorMessage);


            //if (0.GetHashCode() == 0)
            //{
            //    throw new NotImplementedException();
            //}
        }
        static string ToStringReal(TokenExpression ex)
        {
            if (ex == null)
            {
                return("");
            }
            StringBuilder        sb = new StringBuilder();
            StringWriter         sw = new StringWriter(sb);
            MyIndentedTextWriter tw = new MyIndentedTextWriter(sw);

            ToStringReal(ex, tw);
            return(sb.ToString());
        }
Beispiel #7
0
        string GetFunctionName(TokenExpression functionNameToken, string className)
        {
            StringBuilder sb = new StringBuilder();

            foreach (var token in functionNameToken.Subexpressions)
            {
                if (token.TokenType != TokenType.OpenParenthesis)
                {
                    if (token.TokenType == TokenType.ScopeResolution)
                    {
                        if (!string.IsNullOrEmpty(className))
                        {
                            sb.Length = 0;
                        }
                        else
                        {
                            sb.Append("@");
                        }
                    }
                    else
                    {
                        sb.Append(token.Token.Value);
                    }
                }
            }
            string functionName = sb.ToString();
            int    indexOfAt    = functionName.IndexOf('@');

            if (indexOfAt >= 0)
            {
                className    = functionName.Substring(0, indexOfAt);
                functionName = functionName.Substring(indexOfAt + 1);
            }

            if (string.IsNullOrEmpty(className))
            {
                return(functionName);
            }
            else
            {
                if (functionName == className)
                {
                    return(className + "@0");
                }
                if (functionName == "~" + className)
                {
                    return(className + "@1");
                }
                return(className + "@" + functionName);
            }
        }
Beispiel #8
0
        private void DefineZeroFunction()
        {
            Function        zeroFunction      = Functions.Get("0");
            TokenExpression zeroFunctionBlock = new TokenExpression(TokenType.Block);

            foreach (var pair in this.ArraySizeExpressions)
            {
                var global = pair.Key as Global;
                if (global != null)
                {
                    AddArrayDeclarationToBlock(zeroFunctionBlock, global);
                }
            }
            this.FunctionDefinitionTokens[zeroFunction] = zeroFunctionBlock;
        }
Beispiel #9
0
 public static IEnumerable <TokenExpression> TokensWhereRecursive(this TokenExpression token, TokenType tokenType)
 {
     if (token.TokenType == tokenType)
     {
         yield return(token);
     }
     foreach (var subexpression in token.Subexpressions)
     {
         var whereRecursive = TokensWhereRecursive(subexpression, tokenType);
         foreach (var w in whereRecursive)
         {
             yield return(w);
         }
     }
 }
Beispiel #10
0
        private void CreateSymbolForConst(TokenExpression constDeclarationToken, string className)
        {
            var variables = GetVariablesInVariableDeclaration(constDeclarationToken.Subexpressions[1]);

            foreach (var variable in variables)
            {
                string constantName = variable.Name;
                if (!string.IsNullOrEmpty(className))
                {
                    constantName = className + "." + constantName;
                }

                var constant = Constants.Get(constantName);
                constant.SetVariableType(variable);
            }
        }
 private void RaiseError(string errorMessage, TokenExpression token)
 {
     if (token != null)
     {
         errorMessage = "Line " + (token.Row + 1).ToString() + ", Column " + (token.Column + 1).ToString() + ": " + errorMessage;
         if (token.FileName != null)
         {
             errorMessage = "In File: " + token.FileName + Environment.NewLine + errorMessage;
         }
     }
     if (Error != null)
     {
         Error(this, new ErrorEventArgs(new Exception(errorMessage)));
     }
     Errors.Add(errorMessage);
 }
        public void SetVariableInitialValue(TokenExpression variableDeclaration, string className, bool isConst)
        {
            var variableDeclarationList    = variableDeclaration.Subexpressions[1];
            var variableDeclarationEntries = variableDeclarationList.Subexpressions.TokensWhere(TokenType.VariableDeclarationEntry);

            TokenExpression lastExpression = null;

            foreach (var entry in variableDeclarationEntries)
            {
                //entry: identifier [arraybounds] [initialvalue]
                string    name      = null;
                var       nameToken = entry.GetFirstSubexpression(TokenType.Identifier);
                IVariable variable  = null;
                if (nameToken != null)
                {
                    name = nameToken.Token.Value;
                    if (!String.IsNullOrEmpty(className))
                    {
                        name = className + "." + name;
                    }
                    variable = Symbols.GetOrNull(name);
                }
                if (variable != null)
                {
                    var initialValue = entry.Subexpressions.TokensWhere(TokenType.VariableInitialValue).FirstOrDefault();
                    if (initialValue != null)
                    {
                        lastExpression = SetVariableInitialValueToken(variable, initialValue);
                    }
                    else
                    {
                        if (lastExpression != null && isConst)
                        {
                            var nextExpression = new TokenExpression(TokenType.Plus);
                            nextExpression.Token = new Token("+");
                            nextExpression.Subexpressions.Add(lastExpression);
                            var numberToken = new TokenExpression(TokenType.Number);
                            numberToken.Token = new Token("1");
                            nextExpression.Subexpressions.Add(numberToken);

                            initialValueExpressions[variable] = nextExpression;
                            lastExpression = nextExpression;
                        }
                    }
                }
            }
        }
Beispiel #13
0
        private Variable[] GetVariablesInFunctionParameters(TokenExpression functionParameterListToken)
        {
            List <Variable> list = new List <Variable>();

            foreach (var entry in functionParameterListToken.Subexpressions)
            {
                var dataTypeToken      = entry.Subexpressions[0];
                var parameterNameToken = entry.Subexpressions[1];

                var    dataType      = GetDataType(dataTypeToken);
                string parameterName = parameterNameToken.Token.Value;
                var    newVariable   = new Variable(parameterName, dataType.DataType, dataType.StructType, dataType.ArrayDimensions);
                list.Add(newVariable);

                if (dataType.DataType.IsPrimitiveRefType())
                {
                    var voidParameter = new Variable("<void>", DataType.Void, 0, 0);
                    list.Add(voidParameter);
                }
            }
            return(list.ToArray());
        }
Beispiel #14
0
        private Variable[] GetVariablesInVariableDeclaration(TokenExpression variableDeclarationToken)
        {
            var dataTypeToken = variableDeclarationToken.Subexpressions[0];
            var variablesList = variableDeclarationToken.Subexpressions[1].Subexpressions;

            var dataType = GetDataType(dataTypeToken);

            List <Variable> variables = new List <Variable>();

            foreach (var entry in variablesList)
            {
                string variableName = entry.Subexpressions[0].Token.Value;
                var    newVariable  = new Variable(variableName, dataType.DataType, dataType.StructType, dataType.ArrayDimensions);
                newVariable.Root = ainFile;
                variables.Add(newVariable);
                if (entry.Subexpressions.Count > 1 && entry.Subexpressions[1].TokenType == TokenType.ArrayBoundsDeclaration)
                {
                    //due to bugs, it is treating expressions as separate dimension values, so parse it with the second pass first
                    var boundsDeclaration = entry.Subexpressions[1];
                    if (boundsDeclaration.Subexpressions.Count > 1)
                    {
                        var secondPass = new SecondPass(this);
                        var sizeTokens = secondPass.CompileTokens(boundsDeclaration.Subexpressions);
                        boundsDeclaration.Subexpressions.Clear();
                        boundsDeclaration.Subexpressions.AddRange(sizeTokens);
                    }

                    this.ArraySizeExpressions[newVariable] = boundsDeclaration;
                }
                if (newVariable.DataType.IsPrimitiveRefType())
                {
                    newVariable      = new Variable("<void>", DataType.Void, 0, 0);
                    newVariable.Root = ainFile;
                    variables.Add(newVariable);
                }
            }

            return(variables.ToArray());
        }
        private TokenExpression SetVariableInitialValueToken(IVariable variable, TokenExpression variableInitialValueToken)
        {
            //initialvalue: [=], expression
            var reader = new TokenReader(variableInitialValueToken.Subexpressions);

            var lastReader = this.reader;

            this.reader = reader;
            var assign     = ReadToken(TokenType.Assign);
            var expression = ReadToken(TokenType.Expression);

            if (expression != null)
            {
                if (reader.Index < variableInitialValueToken.Subexpressions.Count)
                {
                    //parse error
                }

                initialValueExpressions.Set(variable, expression);
            }
            this.reader = lastReader;
            return(expression);
        }
Beispiel #16
0
        private void AddArrayDeclarationToBlock(TokenExpression block, IVariable member)
        {
            block.Subexpressions.Add(new TokenExpression(member.Name));
            block.Subexpressions.Add(new TokenExpression("."));
            block.Subexpressions.Add(new TokenExpression("Alloc"));
            block.Subexpressions.Add(new TokenExpression("("));
            int count = 0;

            foreach (var numberFromForEach in this.ArraySizeExpressions[member].Subexpressions)
            {
                var number = numberFromForEach;
                if (count > 0)
                {
                    block.Subexpressions.Add(new TokenExpression(TokenType.Comma));
                }
                if (number.TokenType != TokenType.Number)
                {
                    var secondPass   = new SecondPass(this);
                    var initialValue = secondPass.EvaluateConstExpression(number, DataType.Int, true);
                    if (initialValue != null && initialValue.DataType == DataType.Int)
                    {
                        number = new TokenExpression(initialValue.IntValue.ToString());
                    }
                    else
                    {
                        RaiseError("Unable to parse array size as a constant", number);
                    }
                }

                block.Subexpressions.Add(number.Clone());
                count++;
            }

            //block.Subexpressions.Add(this.ArraySizeExpressions[member].Clone());
            block.Subexpressions.Add(new TokenExpression(")"));
            block.Subexpressions.Add(new TokenExpression(";"));
        }
Beispiel #17
0
 string GetFunctionName(TokenExpression functionNameToken)
 {
     return(GetFunctionName(functionNameToken, null));
 }
        public InitialValue EvaluateConstExpression(TokenExpression expression, bool constOnly)
        {
            if (expression == null)
            {
                return(null);
            }
            //leaf? )
            if (expression.Subexpressions.Count == 0)
            {
                if (expression.TokenType == TokenType.Identifier)
                {
                    IVariable variable = Symbols.GetOrNull(expression.Token.Value);
                    if (variable == null)
                    {
                        return(null);
                    }
                    if (constOnly)
                    {
                        if (Parent.Constants.Contains(expression.Token.Value))
                        {
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    if (InitialValues.ContainsKey(variable))
                    {
                        return(InitialValues[variable]);
                    }
                    else
                    {
                        if (variable.DataType.IsInteger())
                        {
                            return(new InitialValue(0));
                        }
                        else if (variable.DataType.IsFloat())
                        {
                            return(new InitialValue(0.0f));
                        }
                        else if (variable.DataType.IsString())
                        {
                            return(new InitialValue(""));
                        }
                        else if (variable.DataType == DataType.Bool || variable.DataType == DataType.RefBool)
                        {
                            return(new InitialValue(false));
                        }
                        else if (variable is Function)
                        {
                            return(new InitialValue(variable.Index));
                        }
                    }
                    return(null);
                }
                else if (expression.TokenType == TokenType.Number)
                {
                    if (expression.Token.IsInt())
                    {
                        return(new InitialValue(expression.Token.ToInt()));
                    }
                    else if (expression.Token.IsFloat())
                    {
                        return(new InitialValue(expression.Token.ToFloat()));
                    }
                }
                else if (expression.TokenType == TokenType.StringLiteral)
                {
                    return(new InitialValue(expression.Token.Value));
                }
                else if (expression.TokenType == TokenType.CharLiteral)
                {
                    var bytes = Extensions.BinaryEncoding.GetBytes(expression.Token.Value);
                    if (bytes.Length > 1)
                    {
                        return(new InitialValue(bytes[1] * 256 + bytes[0]));
                    }
                    else
                    {
                        return(new InitialValue(bytes[0]));
                    }
                }
                return(null);
            }
            //unary operator?
            if (expression.Subexpressions.Count == 1)
            {
                var a = EvaluateConstExpression(expression.Subexpressions[0], constOnly);
                if (a == null)
                {
                    return(null);
                }

                switch (expression.TokenType)
                {
                case TokenType.Complement:
                {
                    if (a.DataType == DataType.Int || a.DataType == DataType.Bool)
                    {
                        return(new InitialValue(~a.IntValue));
                    }
                    return(null);
                }

                case TokenType.Not:
                {
                    if (a.DataType == DataType.Int || a.DataType == DataType.Bool)
                    {
                        return(new InitialValue(a.IntValue != 0));
                    }
                    if (a.DataType == DataType.Float)
                    {
                        return(new InitialValue(a.FloatValue != 0));
                    }
                    return(null);
                }

                case TokenType.Negative:
                {
                    if (a.DataType == DataType.Int || a.DataType == DataType.Bool)
                    {
                        return(new InitialValue(-a.IntValue));
                    }
                    else if (a.DataType == DataType.Float)
                    {
                        return(new InitialValue(-a.FloatValue));
                    }
                    return(null);
                }

                case TokenType.Positive:
                case TokenType.PostDecrement:
                case TokenType.PostIncrement:
                {
                    if (a.DataType == DataType.Int || a.DataType == DataType.Bool || a.DataType == DataType.Float)
                    {
                        return(a);
                    }
                    return(null);
                }

                case TokenType.PreIncrement:
                {
                    if (a.DataType == DataType.Int || a.DataType == DataType.Bool)
                    {
                        return(new InitialValue(a.IntValue + 1));
                    }
                    else if (a.DataType == DataType.Float)
                    {
                        return(new InitialValue(a.FloatValue + 1.0f));
                    }
                    return(null);
                }

                case TokenType.PreDecrement:
                {
                    if (a.DataType == DataType.Int || a.DataType == DataType.Bool)
                    {
                        return(new InitialValue(a.IntValue - 1));
                    }
                    else if (a.DataType == DataType.Float)
                    {
                        return(new InitialValue(a.FloatValue - 1.0f));
                    }
                    return(null);
                }

                case TokenType.AddressOf:
                {
                    if (a.DataType == DataType.Int)
                    {
                        if (expression.Subexpressions[0].TokenType == TokenType.Identifier && Symbols[expression.Subexpressions[0].Token.Value] is Function)
                        {
                            return(a);
                        }
                    }
                    return(null);
                }
                }
                return(null);
            }
            //binary expression?
            if (expression.Subexpressions.Count == 2)
            {
                var a = EvaluateConstExpression(expression.Subexpressions[0], constOnly);
                var b = EvaluateConstExpression(expression.Subexpressions[1], constOnly);

                //cast expressions (expressed as a functioncall)
                if (expression.TokenType == TokenType.FunctionCall && b != null)
                {
                    var exprA = expression.Subexpressions[0];
                    if (exprA.TokenType == TokenType.String)
                    {
                        if (b.DataType == DataType.String)
                        {
                            return(b);
                        }
                        else
                        {
                            return(new InitialValue(b.GetValue()));
                        }
                    }
                    else if (exprA.TokenType == TokenType.Float)
                    {
                        InitialValue v = new InitialValue();
                        if (v.SetValue(DataType.Float, b.GetValue()))
                        {
                            return(v);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else if (exprA.TokenType == TokenType.Int)
                    {
                        InitialValue v = new InitialValue();
                        if (v.SetValue(DataType.Int, b.GetValue()))
                        {
                            return(v);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }

                if (expression.TokenType == TokenType.Assign)
                {
                    return(b);
                }

                if (a == null || b == null)
                {
                    return(null);
                }

                if (a.DataType == DataType.Float || b.DataType == DataType.Float)
                {
                    float floatA;
                    float floatB;

                    if (a.DataType == DataType.Int || a.DataType == DataType.Bool)
                    {
                        floatA = a.IntValue;
                    }
                    else if (a.DataType == DataType.Float)
                    {
                        floatA = a.FloatValue;
                    }
                    else
                    {
                        return(null);
                    }

                    if (b.DataType == DataType.Int || b.DataType == DataType.Bool)
                    {
                        floatB = b.IntValue;
                    }
                    else if (b.DataType == DataType.Float)
                    {
                        floatB = b.FloatValue;
                    }
                    else
                    {
                        return(null);
                    }

                    switch (expression.TokenType)
                    {
                    case TokenType.Multiply:
                    case TokenType.MultiplyAssign:
                        return(new InitialValue(floatA * floatB));

                    case TokenType.Divide:
                    case TokenType.DivideAssign:
                        return(new InitialValue(floatA / floatB));

                    case TokenType.Modulo:
                    case TokenType.ModuloAssign:
                        return(new InitialValue(floatA % floatB));

                    case TokenType.Plus:
                    case TokenType.PlusAssign:
                        return(new InitialValue(floatA + floatB));

                    case TokenType.Minus:
                    case TokenType.MinusAssign:
                        return(new InitialValue(floatA - floatB));

                    case TokenType.LeftShift:
                    case TokenType.LeftShiftAssign:
                        return(new InitialValue((int)floatA << (int)floatB));

                    case TokenType.RightShift:
                    case TokenType.RightShiftAssign:
                        return(new InitialValue((int)floatA << (int)floatB));

                    case TokenType.LessThan:
                        return(new InitialValue(floatA < floatB));

                    case TokenType.LessThanOrEqualTo:
                        return(new InitialValue(floatA <= floatB));

                    case TokenType.GreaterThan:
                        return(new InitialValue(floatA > floatB));

                    case TokenType.GreaterThanOrEqualTo:
                        return(new InitialValue(floatA >= floatB));

                    case TokenType.EqualTo:
                        return(new InitialValue(floatA == floatB));

                    case TokenType.NotEqualTo:
                        return(new InitialValue(floatA != floatB));

                    case TokenType.And:
                    case TokenType.AndAssign:
                        return(new InitialValue((int)floatA & (int)floatB));

                    case TokenType.Xor:
                    case TokenType.XorAssign:
                        return(new InitialValue((int)floatA ^ (int)floatB));

                    case TokenType.Or:
                    case TokenType.OrAssign:
                        return(new InitialValue((int)floatA | (int)floatB));

                    case TokenType.LogicalAnd:
                        return(new InitialValue((floatA != 0) && (floatB != 0)));

                    case TokenType.LogicalOr:
                        return(new InitialValue((floatA != 0) || (floatB != 0)));

                    case TokenType.Assign:
                        return(new InitialValue(floatB));
                    }
                    return(null);
                }

                if (a.DataType == DataType.String && b.DataType == DataType.String)
                {
                    string stringA = a.StringValue ?? "";
                    string stringB = b.StringValue ?? "";

                    switch (expression.TokenType)
                    {
                    case TokenType.Plus:
                    case TokenType.PlusAssign:
                        return(new InitialValue(stringA + stringB));

                    case TokenType.LessThan:
                        return(new InitialValue(String.Compare(stringA, stringB) < 0));

                    case TokenType.LessThanOrEqualTo:
                        return(new InitialValue(String.Compare(stringA, stringB) <= 0));

                    case TokenType.GreaterThan:
                        return(new InitialValue(String.Compare(stringA, stringB) > 0));

                    case TokenType.GreaterThanOrEqualTo:
                        return(new InitialValue(String.Compare(stringA, stringB) >= 0));

                    case TokenType.EqualTo:
                        return(new InitialValue(stringA == stringB));

                    case TokenType.NotEqualTo:
                        return(new InitialValue(stringA != stringB));

                    case TokenType.LogicalAnd:
                        return(new InitialValue((stringA != "") && (stringB != "")));

                    case TokenType.LogicalOr:
                        return(new InitialValue((stringA != "") || (stringB != "")));

                    case TokenType.Assign:
                        return(new InitialValue(stringB));
                    }
                    return(null);
                }

                {
                    int intA;
                    int intB;

                    if (a.DataType == DataType.Int || a.DataType == DataType.Bool)
                    {
                        intA = a.IntValue;
                    }
                    else
                    {
                        return(null);
                    }

                    if (b.DataType == DataType.Int || b.DataType == DataType.Bool)
                    {
                        intB = b.IntValue;
                    }
                    else
                    {
                        return(null);
                    }

                    switch (expression.TokenType)
                    {
                    case TokenType.Multiply:
                    case TokenType.MultiplyAssign:
                        return(new InitialValue(intA * intB));

                    case TokenType.Divide:
                    case TokenType.DivideAssign:
                        return(new InitialValue(intA / intB));

                    case TokenType.Modulo:
                    case TokenType.ModuloAssign:
                        return(new InitialValue(intA % intB));

                    case TokenType.Plus:
                    case TokenType.PlusAssign:
                        return(new InitialValue(intA + intB));

                    case TokenType.Minus:
                    case TokenType.MinusAssign:
                        return(new InitialValue(intA - intB));

                    case TokenType.LeftShift:
                    case TokenType.LeftShiftAssign:
                        return(new InitialValue(intA << intB));

                    case TokenType.RightShift:
                    case TokenType.RightShiftAssign:
                        return(new InitialValue(intA << intB));

                    case TokenType.LessThan:
                        return(new InitialValue(intA < intB));

                    case TokenType.LessThanOrEqualTo:
                        return(new InitialValue(intA <= intB));

                    case TokenType.GreaterThan:
                        return(new InitialValue(intA > intB));

                    case TokenType.GreaterThanOrEqualTo:
                        return(new InitialValue(intA >= intB));

                    case TokenType.EqualTo:
                        return(new InitialValue(intA == intB));

                    case TokenType.NotEqualTo:
                        return(new InitialValue(intA != intB));

                    case TokenType.And:
                    case TokenType.AndAssign:
                        return(new InitialValue(intA & intB));

                    case TokenType.Xor:
                    case TokenType.XorAssign:
                        return(new InitialValue(intA ^ intB));

                    case TokenType.Or:
                    case TokenType.OrAssign:
                        return(new InitialValue(intA | intB));

                    case TokenType.LogicalAnd:
                        return(new InitialValue((intA != 0) && (intB != 0)));

                    case TokenType.LogicalOr:
                        return(new InitialValue((intA != 0) || (intB != 0)));

                    case TokenType.Assign:
                        return(new InitialValue(intB));
                    }
                    return(null);
                }
            }
            return(null);
        }
        private TokenExpression ReadToken(TokenReader reader, TokenType tokenType)
        {
            int startIndex = reader.Index;
            var token      = reader.Peek();

            if (token == null)
            {
                goto leave;
            }
            switch (tokenType)
            {
            default:
            {
                if (token.TokenType == tokenType)
                {
                    return(reader.Read());
                }
            }
            break;

            case TokenType.Identifier:
            {
                if (token.TokenType == TokenType.Identifier)
                {
                    reader.Read();
                    return(token);
                }
                else if (token.IsBuiltInMethod())
                {
                    var clone = token.Clone();
                    clone.TokenType = TokenType.Identifier;
                    reader.Read();
                    return(clone);
                }
            }
            break;

            case TokenType.SimpleDataType:
            {
                if (token.TokenType == TokenType.Identifier || token.IsDataType() || token.TokenType == TokenType.Struct || token.TokenType == TokenType.Functype)
                {
                    return(reader.Read());
                }
            }
            break;

            case TokenType.FunctionName:
            {
                var match = ReadToken(reader, tokenType, TokenType.Complement, TokenType.Identifier, TokenType.OpenParenthesis);
                if (match != null)
                {
                    return(match);
                }
                match = ReadToken(reader, tokenType, TokenType.Identifier, TokenType.ScopeResolution, TokenType.Complement, TokenType.Identifier, TokenType.OpenParenthesis);
                if (match != null)
                {
                    return(match);
                }
                match = ReadToken(reader, tokenType, TokenType.Identifier, TokenType.ScopeResolution, TokenType.Identifier, TokenType.OpenParenthesis);
                if (match != null)
                {
                    return(match);
                }
                match = ReadToken(reader, tokenType, TokenType.Identifier, TokenType.OpenParenthesis);
                if (match != null)
                {
                    return(match);
                }
            }
            break;

            case TokenType.ArrayType:
            {
                var match = ReadToken(reader, tokenType, TokenType.Array, TokenType.At, TokenType.SimpleDataType, TokenType.At, TokenType.Number);
                if (match != null)
                {
                    return(match);
                }
                match = ReadToken(reader, tokenType, TokenType.Array, TokenType.At, TokenType.SimpleDataType);
                if (match != null)
                {
                    return(match);
                }
            }
            break;

            case TokenType.DataType:
            {
                var match = ReadToken(reader, tokenType, TokenType.Optional, TokenType.Ref, TokenType.Choice, TokenType.ArrayType, TokenType.SimpleDataType);
                if (match != null)
                {
                    return(match);
                }
            }
            break;

            case TokenType.FunctionParameterList:
            {
                //we have already consumed the open parenthesis
                //check for immediately closing the argument list
                var voidToken = ReadToken(reader, TokenType.FunctionParameter, TokenType.Void, TokenType.ClosedParenthesis);

                //TODO fix void SetValue(int nValue, int bUpdate=false);

                if (voidToken != null)
                {
                    return(new TokenExpression(null, tokenType));
                }

                var entryTokens = ReadTokens(reader, true, RepeatStyle.RepeatWithCommaUntilCloseParenthesis, TokenType.FunctionParameter);
                if (entryTokens == null)
                {
                    goto leave;
                }
                return(new TokenExpression(entryTokens, tokenType));

                //List<TokenExpression> parametersList = new List<TokenExpression>();

                //while (true)
                //{
                //    //look for (DataType variableName [ = expression], DataType variableName [ = expression]...)
                //    //or "(void)"
                //    var entryToken = ReadToken(reader, TokenType.FunctionParameter, TokenType.DataType, TokenType.Identifier, TokenType.Optional, TokenType.FunctionParameterInitialValue);
                //    if (entryToken == null) goto leave;
                //    parametersList.Add(entryToken);

                //    var separator = ReadToken(reader, TokenType.First, TokenType.Choice, TokenType.Comma, TokenType.ClosedParenthesis);
                //    if (separator == null) goto leave;

                //    if (separator.TokenType == TokenType.ClosedParenthesis)
                //    {
                //        break;
                //    }
                //}
                //return new TokenExpression(parametersList, tokenType);
            }
            break;

            case TokenType.FunctionParameter:
            {
                var match = ReadToken(reader, tokenType, TokenType.DataType, TokenType.Identifier, TokenType.Optional, TokenType.VariableInitialValue);
                if (match != null)
                {
                    return(match);
                }
            }
            break;

            case TokenType.VariableInitialValue:
            {
                if (token.TokenType != TokenType.Assign)
                {
                    goto leave;
                }
                var tokens = SeekToSeparator(reader);
                return(new TokenExpression(tokens, tokenType));
            }
            break;

            case TokenType.FunctionDeclaration:
            {
                var match = ReadToken(reader, tokenType, TokenType.Pound, TokenType.FunctionName, TokenType.FunctionParameterList);
                if (match == null)
                {
                    match = ReadToken(reader, tokenType, TokenType.DataType, TokenType.FunctionName, TokenType.FunctionParameterList);
                }
                if (match == null)
                {
                    match = ReadToken(reader, tokenType, TokenType.FunctionName, TokenType.FunctionParameterList);
                }
                return(match);
            }
            break;

            case TokenType.VariableDeclaration:
            {
                var match = ReadToken(reader, tokenType, TokenType.DataType, TokenType.VariableDeclarationList);
                if (match != null)
                {
                    return(match);
                }
            }
            break;

            case TokenType.VariableDeclarationList:
            {
                var tokens = ReadTokens(reader, false, RepeatStyle.RepeatWithCommaUntilSemicolon, TokenType.VariableDeclarationEntry);
                if (tokens != null)
                {
                    return(new TokenExpression(tokens, tokenType));
                }
            }
            break;

            case TokenType.VariableDeclarationEntry:
            {
                var match = ReadToken(reader, tokenType, TokenType.Identifier, TokenType.Optional, TokenType.ArrayBoundsDeclaration, TokenType.Optional, TokenType.VariableInitialValue);
                if (match != null)
                {
                    return(match);
                }
            }
            break;

            case TokenType.ConstDeclaration:
            {
                var match = ReadToken(reader, tokenType, TokenType.Const, TokenType.VariableDeclaration);
                if (match != null)
                {
                    return(match);
                }
            }
            break;

            case TokenType.FunctypeDeclaration:
            {
                var match = ReadToken(reader, tokenType, TokenType.Choice, TokenType.Functype, TokenType.Delegate, TokenType.DataType, TokenType.FunctionName, TokenType.FunctypeParameterList, TokenType.Semicolon);
                if (match != null)
                {
                    return(match);
                }
            }
            break;

            case TokenType.FunctypeParameterList:
            {
                var match = ReadTokens(reader, true, RepeatStyle.RepeatWithCommaUntilCloseParenthesis, TokenType.FunctypeParameterEntry);
                if (match != null)
                {
                    return(new TokenExpression(match, tokenType));
                }
                var match2 = ReadToken(reader, tokenType, TokenType.Void, TokenType.ClosedParenthesis);
                if (match2 != null)
                {
                    return(match2);
                }
            }
            break;

            case TokenType.FunctypeParameterEntry:
            {
                //may contain both data type and name of a parameter, discard the name.
                var match = ReadToken(reader, TokenType.FunctypeParameterEntry, TokenType.DataType, TokenType.Optional, TokenType.Identifier);
                if (match == null)
                {
                    goto leave;
                }
                //return just the data type
                return(match.Subexpressions[0]);
            }
            break;

            case TokenType.ArrayBoundsDeclaration:
            {
                if (token.TokenType != TokenType.OpenBracket)
                {
                    goto leave;
                }
                var tokens = SeekToBraceEnd(reader);
                if (tokens == null)
                {
                    goto leave;
                }
                var endToken = reader.Read();
                if (endToken == null || endToken.TokenType != TokenType.CloseBracket)
                {
                    goto leave;
                }
                var nextToken = reader.Peek();
                if (nextToken != null && nextToken.TokenType == TokenType.OpenBracket)
                {
                    var nextArrayBoundDeclaration = ReadToken(reader, TokenType.ArrayBoundsDeclaration);
                    if (nextArrayBoundDeclaration != null)
                    {
                        tokens.AddRange(nextArrayBoundDeclaration.Subexpressions);
                    }
                }
                return(new TokenExpression(tokens, tokenType));
            }
            break;

            case TokenType.Block:
            {
                if (token.TokenType == TokenType.OpenBrace)
                {
                    var tokens = SeekToBraceEnd(reader);
                    if (tokens == null)
                    {
                        goto leave;
                    }
                    var closeBraceToken = reader.Read();
                    if (closeBraceToken == null || closeBraceToken.TokenType != TokenType.CloseBrace)
                    {
                        goto leave;
                    }
                    return(new TokenExpression(tokens, TokenType.Block));
                }
                else
                {
                    this.lastDesiredToken = TokenType.OpenBrace;
                    this.lastFailingToken = reader.Peek();
                    goto leave;
                }
            }
            break;

            case TokenType.ClassDefinition:
            {
                var match = ReadToken(reader, tokenType, TokenType.Choice, TokenType.Struct, TokenType.Class, TokenType.Identifier, TokenType.ClassDefinitionEntries, TokenType.Semicolon);
                if (match != null)
                {
                    return(match);
                }
                //if (token.TokenType == TokenType.Class || token.TokenType == TokenType.Struct)
                //{
                //    var classToken = reader.Read();
                //    var identifier = ReadToken(reader, TokenType.Identifier);
                //    if (identifier == null) goto leave;

                //    var openBrace = ReadToken(reader, TokenType.OpenBrace);
                //    if (openBrace == null) goto leave;

                //    var list = ReadTokens(reader, true, RepeatStyle.RepeatUntilEndOfBlock, TokenType.ClassDefinitionEntry);

                //    var semicolon = ReadToken(reader, TokenType.Semicolon);

                //    //var list = new List<TokenExpression>();
                //    //list.Add(classToken);
                //    //list.Add(identifier);
                //    //while (true)
                //    //{
                //    //    var closeBrace = ReadToken(reader, TokenType.CloseBrace);
                //    //    if (closeBrace != null)
                //    //    {
                //    //        break;
                //    //    }
                //    //    var entry = ReadToken(reader, TokenType.ClassDefinitionEntry);
                //    //    if (entry == null) goto leave;
                //    //    list.Add(entry);
                //    //}
                //    return new TokenExpression(list, tokenType);
                //}
            }
            break;

            case TokenType.ClassDefinitionEntries:
            {
                //open brace, list of class definition entries, close brace
                var openBraceToken = ReadToken(reader, TokenType.OpenBrace);
                if (openBraceToken == null)
                {
                    this.lastDesiredToken = TokenType.OpenBrace;
                    this.lastFailingToken = reader.Peek();
                    goto leave;
                }
                var entries = ReadTokens(reader, true, RepeatStyle.RepeatUntilEndOfBlock, TokenType.ClassDefinitionEntry);
                if (entries == null)
                {
                    goto leave;
                }
                return(new TokenExpression(entries, tokenType));
            }
            break;

            case TokenType.ClassDefinitionEntry:
            {
                //todo: constant value

                var match = ReadToken(reader, tokenType, TokenType.FunctionDeclaration, TokenType.Choice, TokenType.Semicolon, TokenType.Block);
                if (match != null)
                {
                    return(match);
                }
                match = ReadToken(reader, tokenType, TokenType.ConstDeclaration);
                if (match != null)
                {
                    return(match);
                }
                match = ReadToken(reader, tokenType, TokenType.VariableDeclaration);
                if (match != null)
                {
                    return(match);
                }
                match = ReadToken(reader, tokenType, TokenType.Choice, TokenType.Public, TokenType.Private, TokenType.Colon);
                if (match != null)
                {
                    return(match);
                }
            }
            break;

            case TokenType.GlobalGroupDeclaration:
            {
                var globalGroupToken = ReadToken(reader, TokenType.GlobalGroup);
                var groupName        = ReadToken(reader, TokenType.Identifier);
                var openBrace        = ReadToken(reader, TokenType.OpenBrace);
                if (globalGroupToken == null || groupName == null || openBrace == null)
                {
                    return(null);
                }
                var entries = ReadTokens(reader, false, RepeatStyle.RepeatUntilEndOfBlock, TokenType.VariableDeclaration);

                if (entries != null)
                {
                    return(new TokenExpression(Enumerable.Repeat(groupName, 1).Concat(entries), tokenType));
                }
            }
            break;

            case TokenType.HllDeclaration:
            {
                var hllToken    = ReadToken(reader, TokenType.Hll);
                var libraryName = ReadToken(reader, TokenType.Identifier);
                var openBrace   = ReadToken(reader, TokenType.OpenBrace);
                if (hllToken == null || libraryName == null || openBrace == null)
                {
                    return(null);
                }
                var entries = ReadTokens(reader, TokenType.ExpressionAndSemicolon, false, RepeatStyle.RepeatUntilEndOfBlock, TokenType.FunctionDeclaration, TokenType.Semicolon);

                if (entries != null)
                {
                    return(new TokenExpression(Enumerable.Repeat(libraryName, 1).Concat(entries.TokensWhereRecursiveFirst(TokenType.FunctionDeclaration)), tokenType));
                }
            }
            break;
            }
            return(null);

leave:
            reader.Index = startIndex;
            return(null);
        }
        private TokenExpression ReadToken(TokenReader reader, TokenType returnType, params TokenType[] tokenTypes)
        {
            int startingIndex           = reader.Index;
            List <TokenExpression> list = new List <TokenExpression>();

            bool isOptional      = false;
            bool isChoice        = false;
            bool ignoreNextToken = false;

            for (int i = 0; i < tokenTypes.Length; i++)
            {
                var tokenType = tokenTypes[i];
                if (tokenType == TokenType.Optional)
                {
                    isOptional = true;
                    continue;
                }
                if (tokenType == TokenType.Choice)
                {
                    isChoice = true;
                    continue;
                }
                if (ignoreNextToken)
                {
                    ignoreNextToken = false;
                    continue;
                }

                int currentTokenIndex = reader.Index;
                var token             = ReadToken(reader, tokenType);
                if (token != null)
                {
                    list.Add(token);
                    isOptional = false;
                    if (isChoice)
                    {
                        ignoreNextToken = true;
                        isChoice        = false;
                    }
                }
                else
                {
                    if (isChoice)
                    {
                        isOptional = true;
                        isChoice   = false;
                    }
                    if (isOptional)
                    {
                        reader.Index = currentTokenIndex;
                        isOptional   = false;
                    }
                    else
                    {
                        if (this.lastFailingToken == null)
                        {
                            this.lastDesiredToken = tokenType;
                            this.lastFailingToken = reader.Peek();
                        }
                        reader.Index = startingIndex;
                        return(null);
                    }
                }
            }
            this.lastFailingToken = null;
            return(new TokenExpression(list, returnType));
        }
        private void IncludeFile(MyTextReader2 tr, List <TokenExpression> tokens, string fileName)
        {
            while (true)
            {
                tr.EatWhiteSpace();
                int    row        = tr.Row;
                int    column     = tr.Column;
                string trFileName = tr.FileName;
                var    token      = tr.ReadToken();

                if (token == null)
                {
                    break;
                }
                var tokenExpression = new TokenExpression(token);
                tokenExpression.Row      = row;
                tokenExpression.Column   = column;
                tokenExpression.FileName = trFileName;
                if (tokenExpression.TokenType == TokenType.Pound)
                {
                    var includeToken = tr.PeekToken();
                    if (includeToken.Value.Equals("include", StringComparison.OrdinalIgnoreCase))
                    {
                        includeToken = tr.ReadToken();
                        var fileNameToken = tr.PeekToken();
                        if (fileNameToken.IsQuoted)
                        {
                            fileNameToken = tr.ReadToken();
                            //If it's a .HLL file, load it as an HLL file instead
                            string includeFileName = tr.CanonicalizeFileName(fileNameToken.Value);
                            string includeExt      = Path.GetExtension(includeFileName).ToLowerInvariant();
                            if (includeExt == ".hll")
                            {
                                string alias = Path.GetFileNameWithoutExtension(includeFileName);
                                IncludeHll(includeFileName, alias);
                            }
                            else
                            {
                                try
                                {
                                    tr.IncludeTextReader(includeFileName);
                                }
                                catch (IOException)
                                {
                                    throw;
                                }
                            }
                            continue;
                        }
                        else
                        {
                            tr.PutbackToken(includeToken);
                        }
                    }
                }

                if (tokenExpression.IsMacro())
                {
                    switch (tokenExpression.TokenType)
                    {
                    case TokenType.FileMacro:
                        tokenExpression.Token = new Token(tr.FileName);
                        tokenExpression.Token.QuoteCharacter = '"';
                        tokenExpression.TokenType            = TokenType.StringLiteral;
                        break;

                    case TokenType.LineMacro:
                        tokenExpression.Token = new Token((row + 1).ToString());
                        tokenExpression.Token.QuoteCharacter = '"';
                        tokenExpression.TokenType            = TokenType.StringLiteral;
                        break;

                    case TokenType.FuncMacro:
                        break;

                    case TokenType.DateMacro:
                        StringBuilder dateString = new StringBuilder();
                        dateString.Append(DateTime.Today.ToString("yyyy/MM/dd"));
                        if (dateString[5] == '0')
                        {
                            dateString[5] = ' ';
                        }
                        if (dateString[8] == '0')
                        {
                            dateString[8] = ' ';
                        }
                        tokenExpression.Token = new Token(dateString.ToString());
                        tokenExpression.Token.QuoteCharacter = '"';
                        tokenExpression.TokenType            = TokenType.StringLiteral;
                        break;

                    case TokenType.TimeMacro:
                        tokenExpression.Token = new Token(DateTime.Now.ToString("HH:mm:ss"));
                        tokenExpression.Token.QuoteCharacter = '"';
                        tokenExpression.TokenType            = TokenType.StringLiteral;
                        break;
                    }
                }
                tokens.Add(tokenExpression);
            }
        }
        private void RaiseBraceError(TokenExpression token, char op)
        {
            string errorMessage = "Found '" + token.Token.Value + "', but it does not match '" + op + "'";

            RaiseError(errorMessage, token);
        }
        private List <TokenExpression> SeekToBraceEnd(TokenReader reader)
        {
            List <char> matchStack = new List <char>();
            int         stackPos   = 0;

            var list = new List <TokenExpression>();

            TokenExpression token = null;

            while (true)
            {
                char op;
                token = reader.Peek();
                if (token == null)
                {
                    break;
                }
                switch (token.TokenType)
                {
                case TokenType.OpenParenthesis:
                    matchStack.SetOrAdd(stackPos++, '(');
                    if (matchStack.Count == 1)
                    {
                        reader.Index++;
                        continue;
                    }
                    break;

                case TokenType.OpenBracket:
                    matchStack.SetOrAdd(stackPos++, '[');
                    if (matchStack.Count == 1)
                    {
                        reader.Index++;
                        continue;
                    }
                    break;

                case TokenType.OpenBrace:
                    matchStack.SetOrAdd(stackPos++, '{');
                    if (matchStack.Count == 1)
                    {
                        reader.Index++;
                        continue;
                    }
                    break;

                case TokenType.ClosedParenthesis:
                    op = matchStack.GetOrNull(--stackPos);
                    if (op != '(')
                    {
                        RaiseBraceError(token, op);
                        return(null);
                    }
                    if (stackPos == 0)
                    {
                        goto leave;
                    }
                    break;

                case TokenType.CloseBracket:
                    op = matchStack.GetOrNull(--stackPos);
                    if (op != '[')
                    {
                        RaiseBraceError(token, op);
                        return(null);
                    }
                    if (stackPos == 0)
                    {
                        goto leave;
                    }
                    break;

                case TokenType.CloseBrace:
                    op = matchStack.GetOrNull(--stackPos);
                    if (op != '{')
                    {
                        RaiseBraceError(token, op);
                        return(null);
                    }
                    if (stackPos == 0)
                    {
                        goto leave;
                    }
                    break;
                }
                reader.Index++;
                list.Add(token);
            }
leave:
            if (stackPos != 0)
            {
                RaiseError("Reached end of input, but brace tokens are not matched.", null);
            }
            return(list);
            //error:
            //    ;
            //    RaiseError("Parentheses, braces, or brackets are imbalanced", token);
            //    return null;
        }
Beispiel #24
0
 private Function CreateSymbolForFunction(TokenExpression functionDeclarationToken)
 {
     return(CreateSymbolForFunction(functionDeclarationToken, null));
 }
Beispiel #25
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));
        }
Beispiel #26
0
        private HllFunction CreateSymbolForLibraryFunction(TokenExpression functionDeclarationToken, string libraryName, string libraryAlias)
        {
            var      dataTypeToken = functionDeclarationToken.GetFirstSubexpression(TokenType.DataType);
            Variable dataType;

            if (dataTypeToken != null)
            {
                dataType = GetDataType(dataTypeToken);
            }
            else
            {
                dataType = new Variable("", DataType.Void, -1, 0);
            }
            var    functionNameToken = functionDeclarationToken.GetFirstSubexpression(TokenType.FunctionName);
            string functionName      = GetFunctionName(functionNameToken);

            var library = Libraries.Get(libraryName);

            library.Root        = ainFile;
            library.LibraryName = libraryName;
            string fullName        = libraryAlias + "." + functionName;
            var    libraryFunction = Symbols.GetOrNull(fullName) as HllFunction;

            if (libraryFunction == null)
            {
                libraryFunction = new HllFunction();
                libraryFunction.SetVariableType(dataType);
                libraryFunction.Name          = functionName;
                libraryFunction.ParentLibrary = library;
                libraryFunction.Root          = ainFile;
                libraryFunction.Index         = library.Functions.Count;
                library.Functions.Add(libraryFunction);
                Symbols[fullName] = libraryFunction;
            }

            //add parameters
            var functionParameterListToken = functionDeclarationToken.GetFirstSubexpression(TokenType.FunctionParameterList);

            if (functionParameterListToken != null)
            {
                var parameters = GetVariablesInFunctionParameters(functionParameterListToken);

                if (libraryFunction.Parameters.Count < parameters.Length)
                {
                    libraryFunction.Parameters.Clear();
                    foreach (var parameter in parameters)
                    {
                        int index = libraryFunction.Parameters.Count;
                        if (parameter.DataType != DataType.Void)
                        {
                            var newParameter = new HllFunctionParameter();
                            newParameter.Parent = libraryFunction;
                            newParameter.Root   = ainFile;
                            newParameter.Name   = parameter.Name;
                            newParameter.Index  = index;
                            newParameter.SetVariableType(parameter);
                            libraryFunction.Parameters.Add(newParameter);
                        }
                        else
                        {
                        }
                    }
                    libraryFunction.ParameterCount = libraryFunction.Parameters.Count;
                }
            }
            return(libraryFunction);
        }
        private void PreprocessInclude(string filename, List <TokenExpression> tokens)
        {
            List <TokenExpression> thisFile = new List <TokenExpression>();

            MyTextReader2.UseEscapedStringsDefault = false;
            IncludeFile(filename, thisFile);
            MyTextReader2.UseEscapedStringsDefault = true;
            int    i           = 0;
            int    insideBrace = 0;
            string sourceDir   = Path.GetDirectoryName(filename);

            while (i < thisFile.Count)
            {
                var token = thisFile[i++];
                if (insideBrace > 0)
                {
                    if (token.TokenType == TokenType.OpenBrace)
                    {
                        insideBrace++;
                    }
                    else if (token.TokenType == TokenType.CloseBrace)
                    {
                        insideBrace--;
                    }
                    continue;
                }
                if (token.TokenType == TokenType.OpenBrace)
                {
                    insideBrace++;
                    continue;
                }
                switch (token.Token.Value)
                {
                case "ProjectName":
                {
                    var assign = thisFile[i++];
                    if (assign.TokenType == TokenType.Assign)
                    {
                        var filenameToken = thisFile[i++];
                        if (filenameToken.TokenType == TokenType.StringLiteral)
                        {
                            this.projectName = filenameToken.Token.Value;
                        }
                    }
                }
                break;

                case "CodeName":
                {
                    var assign = thisFile[i++];
                    if (assign.TokenType == TokenType.Assign)
                    {
                        var filenameToken = thisFile[i++];
                        if (filenameToken.TokenType == TokenType.StringLiteral)
                        {
                            this.codeName = filenameToken.Token.Value;
                        }
                    }
                }
                break;

                case "SourceDir":
                {
                    var assign = thisFile[i++];
                    if (assign.TokenType == TokenType.Assign)
                    {
                        var filenameToken = thisFile[i++];
                        if (filenameToken.TokenType == TokenType.StringLiteral)
                        {
                            sourceDir        = Path.Combine(sourceDir, filenameToken.Token.Value);
                            sourceDir        = Path.GetFullPath(sourceDir);
                            mainSourcePrefix = sourceDir + Path.DirectorySeparatorChar;
                        }
                    }
                }
                break;

                case "GameVersion":
                {
                    var assign = thisFile[i++];
                    if (assign.TokenType == TokenType.Assign)
                    {
                        var versionToken = thisFile[i++];
                        if (versionToken.TokenType == TokenType.Number)
                        {
                            this.gameVersion = versionToken.Token.ToInt();
                        }
                    }
                }
                break;

                case "SystemSource":
                case "Source":
                {
                    var assign = thisFile[i++];
                    if (assign.TokenType == TokenType.Assign)
                    {
                        var separator = thisFile[i++];
                        if (separator.TokenType == TokenType.OpenBrace)
                        {
                            while (true)
                            {
                                string nextFileName;
                                var    filenameToken = thisFile[i++];
                                if (filenameToken.TokenType == TokenType.StringLiteral)
                                {
                                    nextFileName = Path.Combine(sourceDir, filenameToken.Token.Value);
                                }
                                else
                                {
                                    break;
                                }
                                separator = thisFile[i++];

                                nextFileName = Path.Combine(sourceDir, nextFileName);

                                string ext = Path.GetExtension(nextFileName).ToLowerInvariant();
                                if (ext == ".jaf")
                                {
                                    IncludeFile(nextFileName, tokens);
                                    var    eofToken      = new TokenExpression(TokenType.Eof);
                                    string nextFileName2 = nextFileName;
                                    if (nextFileName2.StartsWith(this.mainSourcePrefix))
                                    {
                                        nextFileName2 = nextFileName2.Substring(this.mainSourcePrefix.Length);
                                    }

                                    var newFilenameToken = new TokenExpression(nextFileName);
                                    newFilenameToken.TokenType            = TokenType.StringLiteral;
                                    newFilenameToken.Token.QuoteCharacter = '"';
                                    eofToken.Subexpressions.Add(newFilenameToken);

                                    tokens.Add(eofToken);
                                }
                                else if (ext == ".inc")
                                {
                                    PreprocessInclude(nextFileName, tokens);
                                }
                                else if (ext == ".hll")
                                {
                                    string alias = Path.GetFileNameWithoutExtension(nextFileName);
                                    if (separator.TokenType == TokenType.Comma)
                                    {
                                        var aliasToken = thisFile[i++];
                                        if (aliasToken.TokenType == TokenType.StringLiteral)
                                        {
                                            alias = aliasToken.Token.Value;
                                        }
                                        separator = thisFile[i++];
                                    }

                                    IncludeHll(nextFileName, alias);
                                }
                                if (separator.TokenType == TokenType.CloseBrace)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                break;

                case "#":
                {
                    var defineToken = thisFile[i];
                    if (defineToken.Token.Value.Equals("define", StringComparison.OrdinalIgnoreCase))
                    {
                        i++;
                        var symbolNameToken  = thisFile[i++];
                        var symbolValueToken = thisFile[i++];

                        string symbolName = symbolNameToken.Token.Value;
                        if (symbolName.Equals("_AINVERSION", StringComparison.OrdinalIgnoreCase))
                        {
                            this.AinVersion = symbolValueToken.Token.ToInt();
                        }
                        else if (symbolName.Equals("_KEYCODE", StringComparison.OrdinalIgnoreCase))
                        {
                            this.KeyCode = symbolValueToken.Token.ToInt();
                        }
                        else if (symbolName.Equals("_ISAI2FILE", StringComparison.OrdinalIgnoreCase))
                        {
                            if (symbolValueToken.Token.IsInt())
                            {
                                this.IsAi2File = symbolValueToken.Token.ToInt() != 0;
                            }
                            else if (symbolValueToken.Token.Value.Equals("true", StringComparison.OrdinalIgnoreCase))
                            {
                                this.IsAi2File = true;
                            }
                            else if (symbolValueToken.Token.Value.Equals("false", StringComparison.OrdinalIgnoreCase))
                            {
                                this.IsAi2File = false;
                            }
                        }
                        else if (symbolName.Equals("_USESMSG1", StringComparison.OrdinalIgnoreCase))
                        {
                            if (symbolValueToken.Token.IsInt())
                            {
                                this.UsesMsg1 = symbolValueToken.Token.ToInt() != 0;
                            }
                            else if (symbolValueToken.Token.Value.Equals("true", StringComparison.OrdinalIgnoreCase))
                            {
                                this.UsesMsg1 = true;
                            }
                            else if (symbolValueToken.Token.Value.Equals("false", StringComparison.OrdinalIgnoreCase))
                            {
                                this.UsesMsg1 = false;
                            }
                        }
                        else if (symbolName.Equals("_TARGETVM", StringComparison.OrdinalIgnoreCase))
                        {
                            if (symbolValueToken.Token.IsInt())
                            {
                                this.TargetVMVersion = symbolValueToken.Token.ToInt();
                            }
                        }
                    }
                }
                break;
                }
            }
        }
Beispiel #28
0
 private Function CreateSymbolForFunction(TokenExpression functionDeclarationToken, string className)
 {
     return(CreateSymbolForFunction(functionDeclarationToken, className, true));
 }
        static void ToStringReal(TokenExpression ex, MyIndentedTextWriter tw)
        {
            if (ex == null)
            {
                return;
            }
            switch (ex.TokenType)
            {
            default:
                if (!String.IsNullOrEmpty(ex.Token.Value) && ex.Token.Value != "...")
                {
                    tw.Write(ex.Token.Value);
                }
                if (ex.Subexpressions.Count > 0)
                {
                    tw.Write(" ");
                    ToStringReal(ex.Subexpressions, tw);
                }
                break;

            case TokenType.Array:
            case TokenType.AddressOf:
            case TokenType.At:
            case TokenType.Complement:
            case TokenType.Increment:
            case TokenType.Decrement:
                if (!String.IsNullOrEmpty(ex.Token.Value) && ex.Token.Value != "...")
                {
                    tw.Write(ex.Token.Value);
                }
                if (ex.Subexpressions.Count > 0)
                {
                    ToStringReal(ex.Subexpressions, tw);
                }
                break;

            case TokenType.Block:
                if (!tw.TabsPending)
                {
                    tw.WriteLine();
                }
                tw.WriteLine("{");
                tw.Indent++;
                ToStringReal(ex.Subexpressions, tw);
                tw.Indent--;
                if (!tw.TabsPending)
                {
                    tw.WriteLine();
                }
                tw.WriteLine("}");
                break;

            case TokenType.Statement:
                ToStringReal(ex.Subexpressions, tw);
                tw.WriteLine(";");
                break;

            case TokenType.StringLiteral:
                tw.Write(AssemblerProjectWriter.EscapeAndQuoteString(ex.Token.Value));
                break;

            case TokenType.CharLiteral:
            case TokenType.Message:
                tw.Write(AssemblerProjectWriter.EscapeAndQuoteMessage(ex.Token.Value));
                break;

            case TokenType.ArrayIndex:
                tw.Write("[");
                ToStringReal(ex.Subexpressions, tw);
                tw.Write("]");
                break;

            case TokenType.Assert:
                tw.Write("assert (");
                for (int i = 0; i < ex.Subexpressions.Count; i++)
                {
                    if (i != 0)
                    {
                        tw.Write(", ");
                    }
                    ToStringReal(ex.Subexpressions[i], tw);
                }
                tw.Write(")");
                break;

            case TokenType.For:
                tw.Write("for (");
                for (int i = 0; i < 3; i++)
                {
                    if (i != 0)
                    {
                        tw.Write("; ");
                    }
                    var subex = ex.Subexpressions.GetOrNull(i);
                    ToStringReal(subex, tw);
                }
                tw.WriteLine(")");
                ToStringReal(ex.Subexpressions.GetOrNull(3), tw);
                break;

            case TokenType.While:
                tw.Write("while (");
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);
                tw.WriteLine(")");
                ToStringReal(ex.Subexpressions.GetOrNull(1), tw);
                break;

            case TokenType.If:
                tw.Write("if (");
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);
                tw.WriteLine(")");
                ToStringReal(ex.Subexpressions.GetOrNull(1), tw);
                {
                    var subex = ex.Subexpressions.GetOrNull(2);
                    if (subex != null)
                    {
                        ToStringReal(subex, tw);
                    }
                }
                break;

            case TokenType.Switch:
                tw.Write("switch (");
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);
                tw.WriteLine(")");
                ToStringReal(ex.Subexpressions.Skip(1), tw);
                break;

            case TokenType.FunctionCall:
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);
                tw.Write("(");
                ToStringReal(ex.Subexpressions.Skip(1), tw);
                tw.Write(")");
                break;

            case TokenType.PostDecrement:
            case TokenType.PostIncrement:
                ToStringReal(ex.Subexpressions, tw);
                tw.Write(ex.Token.Value);
                break;

            //infix binary operators
            case TokenType.And:
            case TokenType.AndAssign:
            case TokenType.Assign:
            case TokenType.Colon:
            case TokenType.Comma:
            case TokenType.Divide:
            case TokenType.DivideAssign:
            case TokenType.Dot:
            case TokenType.EqualTo:
            case TokenType.LeftShift:
            case TokenType.LeftShiftAssign:
            case TokenType.LessThan:
            case TokenType.LessThanOrEqualTo:
            case TokenType.LogicalAnd:
            case TokenType.LogicalOr:
            case TokenType.Minus:
            case TokenType.MinusAssign:
            case TokenType.Modulo:
            case TokenType.ModuloAssign:
            case TokenType.Multiply:
            case TokenType.MultiplyAssign:
            case TokenType.NotEqualTo:
            case TokenType.Or:
            case TokenType.OrAssign:
            case TokenType.Plus:
            case TokenType.PlusAssign:
            case TokenType.QuestionMark:
            case TokenType.ReferenceAssign:
            case TokenType.ReferenceEqualTo:
            case TokenType.ReferenceNotEqualTo:
            case TokenType.ReferenceSwap:
            case TokenType.RightShift:
            case TokenType.RightShiftAssign:
            case TokenType.Xor:
            case TokenType.XorAssign:
                //output left side
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);

                if (ex.TokenType != TokenType.Comma && ex.TokenType != TokenType.Dot)
                {
                    tw.Write(" ");
                }

                if (String.IsNullOrEmpty(ex.Token.Value) || ex.Token.Value == "...")
                {
                    if (keywordTableInverse.ContainsKey(ex.TokenType))
                    {
                        tw.Write(keywordTableInverse[ex.TokenType]);
                    }
                }
                else
                {
                    tw.Write(ex.Token.Value);
                }
                if (ex.TokenType != TokenType.Dot)
                {
                    tw.Write(" ");
                }

                ToStringReal(ex.Subexpressions.Skip(1), tw);
                break;
            }



            //foreach (var ex in exBase.GetAllSubexpressionsRecursive())
            //{
            //    switch (ex.TokenType)
            //    {
            //        case TokenType.And:
            //            case TokenType.

            //        default:
            //            sb.Append(ex.Token.Value);
            //            break;
            //    }
            //}
            //return sb.ToString();
        }
Beispiel #30
0
 private void CreateSymbolForConst(TokenExpression constDeclarationToken)
 {
     CreateSymbolForConst(constDeclarationToken, null);
 }