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); }
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); }
private void RaiseError2(string errorMessage, TokenExpression tokenExpression) { errorMessage += ": "; if (tokenExpression != null) { errorMessage += tokenExpression.ToStringReal(); } RaiseError(errorMessage, tokenExpression); }
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()); }
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); } }
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; }
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); } } }
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; } } } } }
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()); }
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); }
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(";")); }
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; }
private Function CreateSymbolForFunction(TokenExpression functionDeclarationToken) { return(CreateSymbolForFunction(functionDeclarationToken, null)); }
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)); }
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; } } }
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(); }
private void CreateSymbolForConst(TokenExpression constDeclarationToken) { CreateSymbolForConst(constDeclarationToken, null); }