void AddLocalVariables(AST ast, VariableDefinition[] variableDefinitions) { AST nodeForDefiningGlobalVariables = ast.getChild(0).getChild(0); if (variableDefinitions == null) { return; } foreach (VariableDefinition vd in variableDefinitions) { Token token = new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>", ast.getToken().LineNr, ast.getToken().LinePosition); AST_VariableDeclaration declarationTree = new AST_VariableDeclaration(token, ReturnValueConversions.SystemTypeToReturnValueType(vd.initValue.GetType()), vd.variableName); if (vd.initValue != null) { AST assignmentTree = CreateAssignmentTreeFromInitValue(vd.variableName, vd.initValue); AST declarationAndAssignmentTree = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<DECLARATION_AND_ASSIGNMENT>", declarationTree.getToken().LineNr, declarationTree.getToken().LinePosition)); declarationAndAssignmentTree.addChild(declarationTree); declarationAndAssignmentTree.addChild(assignmentTree); nodeForDefiningGlobalVariables.addChild(declarationAndAssignmentTree); } else { nodeForDefiningGlobalVariables.addChild(declarationTree); } } }
private AST declarationAndAssignment() { #if WRITE_DEBUG_INFO Console.WriteLine("declaration and assignment"); #endif AST_VariableDeclaration declarationTree = declaration(); Token assignmentToken = match(Token.TokenType.ASSIGNMENT); AST expressionTree = expression(); if (expressionTree != null) { AST_Assignment assignmentTree = new AST_Assignment(assignmentToken, declarationTree.Name); assignmentTree.addChild(expressionTree); AST declarationAndAssignmentTree = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<DECLARATION_AND_ASSIGNMENT>", declarationTree.getToken().LineNr, declarationTree.getToken().LinePosition)); declarationAndAssignmentTree.addChild(declarationTree); declarationAndAssignmentTree.addChild(assignmentTree); return(declarationAndAssignmentTree); } else { throw new Error("The expression after = makes no sense", Error.ErrorType.SYNTAX, lookAhead(1).LineNr, lookAhead(1).LinePosition); } }
private AST foreachStuff() { AST statementList = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<FOREACH_STATEMENTS>")); // increase __index__ AST incrementNode = new AST(new Token(Token.TokenType.OPERATOR, "+")); incrementNode.addChild(new AST(new Token(Token.TokenType.NAME, "__index__"))); incrementNode.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "1", new ReturnValue(1.0f)))); AST_Assignment assignmentNode = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__"); assignmentNode.addChild(incrementNode); statementList.addChild(assignmentNode); // if(__index__ >= count(__indexes__)) { break } AST_FunctionCall lengthOfArray = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "count")); AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>")); argumentList.addChild(new Token(Token.TokenType.NAME, "__indexes__")); lengthOfArray.addChild(argumentList); AST breakStatement = new AST_IfNode(new Token(Token.TokenType.IF, "IF")); AST operatorTree = new AST(new Token(Token.TokenType.OPERATOR, ">=")); operatorTree.addChild(new Token(Token.TokenType.NAME, "__index__")); operatorTree.addChild(lengthOfArray); breakStatement.addChild(operatorTree); breakStatement.addChild(new Token(Token.TokenType.BREAK, "break")); statementList.addChild(breakStatement); // @ variable AST_VariableDeclaration declarationTree = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.UNKNOWN_TYPE, "@"); statementList.addChild(declarationTree); AST arrayIndexLookup = new AST(new Token(Token.TokenType.ARRAY_LOOKUP, "__indexes__")); arrayIndexLookup.addChild(new AST(new Token(Token.TokenType.NAME, "__index__"))); AST arrayValueLookup = new AST(new Token(Token.TokenType.ARRAY_LOOKUP, "__array__")); arrayValueLookup.addChild(arrayIndexLookup); AST_Assignment assignmentTree = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "@"); assignmentTree.addChild(arrayValueLookup); statementList.addChild(assignmentTree); return(statementList); }
private AST createParameterDefinition(string typeName, string variableName) { AST parameter = new AST(new Token(Token.TokenType.PARAMETER, "<PARAMETER>")); AST declaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<PARAMETER_DECLARATION>"), ReturnValue.getReturnValueTypeFromString(typeName), variableName); AST assigment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), variableName); parameter.addChild(declaration); parameter.addChild(assigment); return parameter; }
private AST createParameterDefinition(string typeName, string variableName) { AST parameter = new AST(new Token(Token.TokenType.PARAMETER, "<PARAMETER>")); AST declaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<PARAMETER_DECLARATION>"), GetReturnTypeFromString(typeName), variableName); AST assigment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), variableName); parameter.addChild(declaration); parameter.addChild(assigment); return(parameter); }
private AST_VariableDeclaration declaration() { #if WRITE_DEBUG_INFO Console.WriteLine("declaration"); #endif Token typeName = match(Token.TokenType.BUILT_IN_TYPE_NAME); Token variableName = match(Token.TokenType.NAME); AST_VariableDeclaration declarationTree = new AST_VariableDeclaration( new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>", lookAhead(1).LineNr, lookAhead(1).LinePosition), ReturnValue.getReturnValueTypeFromString(typeName.getTokenString()), variableName.getTokenString()); return(declarationTree); }
private AST parameter() { #if WRITE_DEBUG_INFO Console.WriteLine("parameter"); #endif AST parameterTree = new AST(new Token(Token.TokenType.PARAMETER, "<PARAMETER>", lookAhead(1).LineNr, lookAhead(1).LinePosition)); AST type = new AST(match(Token.TokenType.BUILT_IN_TYPE_NAME)); AST name = new AST(match(Token.TokenType.NAME)); AST declaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<PARAMETER_DECLARATION>"), ReturnValue.getReturnValueTypeFromString(type.getTokenString()), name.getTokenString()); AST assigment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), name.getTokenString()); parameterTree.addChild(declaration); parameterTree.addChild(assigment); return(parameterTree); }
private void evaluateReferencesForVAR_DECLARATION(AST tree) { AST_VariableDeclaration varDeclaration = tree as AST_VariableDeclaration; ReturnValueType typeToDeclare = varDeclaration.Type; string variableName = varDeclaration.Name; if (m_currentScope.isDefined(variableName)) { m_errorHandler.errorOccured( new Error("There is already a variable called '" + variableName + "'", Error.ErrorType.LOGIC, tree.getToken().LineNr, tree.getToken().LinePosition)); } else { m_currentScope.define(new VariableSymbol(variableName, typeToDeclare)); #if WRITE_DEBUG_INFO Console.WriteLine("Defined variable with name " + variableName + " and type " + typeToDeclare + " (on line " + tree.getToken().LineNr + ")" + " in " + m_currentScope); #endif } }
void AddLocalVariables(AST ast, VariableDefinition[] variableDefinitions) { AST nodeForDefiningGlobalVariables = ast.getChild(0).getChild(0); if(variableDefinitions == null) { return; } foreach(VariableDefinition vd in variableDefinitions) { Token token = new Token(Token.TokenType.VAR_DECLARATION,"<VAR_DECL>", ast.getToken().LineNr, ast.getToken().LinePosition); AST_VariableDeclaration declarationTree = new AST_VariableDeclaration(token, vd.initValue.getReturnValueType(), vd.variableName); if(vd.initValue != null) { AST assignmentTree = CreateAssignmentTreeFromInitValue(vd.variableName, vd.initValue); AST declarationAndAssignmentTree = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<DECLARATION_AND_ASSIGNMENT>", declarationTree.getToken().LineNr, declarationTree.getToken().LinePosition)); declarationAndAssignmentTree.addChild(declarationTree); declarationAndAssignmentTree.addChild(assignmentTree); nodeForDefiningGlobalVariables.addChild(declarationAndAssignmentTree); } else { nodeForDefiningGlobalVariables.addChild(declarationTree); } } }
private AST loop() { #if WRITE_DEBUG_INFO Console.WriteLine("loop"); #endif AST loopBlockStatements = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<LOOP_BLOCK_STATEMENTS>")); AST_LoopNode loopTree = new AST_LoopNode(match(Token.TokenType.LOOP)); string loopVariableName = "@"; // default name if no name is specified directly after 'loop' keyword bool isForeachLoop = false; if(lookAheadType(1) != Token.TokenType.NEW_LINE) { #if WRITE_DEBUG_INFO Console.WriteLine("foreach loop!"); #endif isForeachLoop = true; // __index__ AST_VariableDeclaration loopIndexDeclaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.NUMBER, "__index__"); loopBlockStatements.addChild(loopIndexDeclaration); AST_Assignment loopIndexAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__"); loopIndexAssignment.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "-1", -1.0f))); loopBlockStatements.addChild(loopIndexAssignment); Token savePoint = lookAhead(1); // will backtrack from here if matching loopVariable + loopRangeExpression fails //Console.WriteLine("Created save point at token " + savePoint); Token loopVariable = null; AST loopRangeExpression = null; // what the loop will loop through if ((lookAheadType (1) == Token.TokenType.NAME && lookAheadType(2) == Token.TokenType.IN) || (lookAheadType (1) == Token.TokenType.NAME && lookAheadType(2) == Token.TokenType.FROM)) { loopVariable = match (Token.TokenType.NAME); if(lookAheadType(1) == Token.TokenType.IN) { match (Token.TokenType.IN); } else if(lookAheadType(1) == Token.TokenType.FROM) { // proceed } try { //Console.WriteLine ("Found a potential loop variable " + loopVariable.getTokenString() + ", trying to match loop range expression with a loop variable"); loopRangeExpression = expression(); if(loopRangeExpression == null) { //Console.WriteLine ("null! Failed to match statement after loop variable, will backtrack and assume this loop does not use a loop variable"); backtrackToToken (savePoint); } else { loopVariableName = loopVariable.getTokenString(); //Console.WriteLine("Success, loop variable is called: " + loopVariableName); } } catch(Error e) { //Console.WriteLine ("Failed to match statement after loop variable, will backtrack and assume this loop does not use a loop variable"); backtrackToToken (savePoint); } } if (loopRangeExpression == null) { //Console.WriteLine ("There is no loop variable, trying to match a bare loop range expression"); loopRangeExpression = expression(); } if (loopRangeExpression == null) { throw new Error ("Failed to match the expression after 'loop'", Error.ErrorType.SYNTAX, loopTree.getToken ().LineNr, loopTree.getToken ().LinePosition); } //Console.WriteLine ("Loop range/array expression: "); //(new ASTPainter ()).PaintAST (loopRangeExpression); // __array__ (is a copy of the array to loop over) AST_VariableDeclaration loopArrayDeclaration = new AST_VariableDeclaration( new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.UNKNOWN_TYPE, "__array__"); loopBlockStatements.addChild(loopArrayDeclaration); AST_Assignment loopArrayAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__array__"); if(loopRangeExpression != null) { loopArrayAssignment.addChild(loopRangeExpression); } else { throw new Error("Can't understand array expression in loop", Error.ErrorType.SYNTAX, loopArrayAssignment.getToken().LineNr, loopArrayAssignment.getToken().LinePosition); } loopBlockStatements.addChild(loopArrayAssignment); // __indexes__ (holds all the indexes in the array, since it works like a SortedDictionary) // __indexes = getIndexes(__array__) AST_VariableDeclaration indexesDeclaration = new AST_VariableDeclaration( new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.UNKNOWN_TYPE, "__indexes__"); loopBlockStatements.addChild(indexesDeclaration); AST_FunctionCall getArrayIndexes = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "GetIndexes")); AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>")); argumentList.addChild(new Token(Token.TokenType.NAME, "__array__")); getArrayIndexes.addChild(argumentList); AST_Assignment indexesAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__indexes__"); indexesAssignment.addChild(getArrayIndexes); loopBlockStatements.addChild(indexesAssignment); } else { #if WRITE_DEBUG_INFO Console.WriteLine("infinite loop!"); #endif } /* * loopParentTree * __index__-declaration * __array__-declaration & assigment * loop tree * loop body * foreach stuff * rest of statements * goto beginning of loop * * */ allowLineBreak(); AST loopBody = statementList(false); loopBody.addChild(new AST(new Token(Token.TokenType.GOTO_BEGINNING_OF_LOOP, "<GOTO_BEGINNING_OF_LOOP>"))); allowLineBreak(); match(Token.TokenType.BLOCK_END); if(isForeachLoop) { loopBody.addChildFirst(foreachStuff(loopVariableName)); } loopTree.addChild(loopBody); loopBlockStatements.addChild(loopTree); AST_LoopBlockNode loopBlock = new AST_LoopBlockNode(new Token(Token.TokenType.LOOP_BLOCK, "<LOOP_BLOCK>")); loopBlock.addChild(loopBlockStatements); return loopBlock; }
private AST foreachStuff(string pLoopVariableName) { AST statementList = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<FOREACH_STATEMENTS>")); // increase __index__ AST incrementNode = new AST(new Token(Token.TokenType.OPERATOR, "+")); incrementNode.addChild(new AST(new Token(Token.TokenType.NAME, "__index__"))); incrementNode.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "1", 1.0f))); AST_Assignment assignmentNode = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__"); assignmentNode.addChild(incrementNode); statementList.addChild(assignmentNode); // if(__index__ >= count(__indexes__)) { break } AST_FunctionCall lengthOfArray = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "Count")); AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>")); argumentList.addChild(new Token(Token.TokenType.NAME, "__indexes__")); lengthOfArray.addChild(argumentList); AST breakStatement = new AST_IfNode(new Token(Token.TokenType.IF, "IF")); AST operatorTree = new AST(new Token(Token.TokenType.OPERATOR, ">=")); operatorTree.addChild(new Token(Token.TokenType.NAME, "__index__")); operatorTree.addChild(lengthOfArray); breakStatement.addChild(operatorTree); breakStatement.addChild(new Token(Token.TokenType.BREAK, "break")); statementList.addChild(breakStatement); // Loop variable AST_VariableDeclaration declarationTree = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.UNKNOWN_TYPE, pLoopVariableName); statementList.addChild(declarationTree); AST arrayIndexLookup = new AST(new Token(Token.TokenType.ARRAY_LOOKUP, "__indexes__")); arrayIndexLookup.addChild(new AST(new Token(Token.TokenType.NAME, "__index__"))); AST arrayValueLookup = new AST(new Token(Token.TokenType.ARRAY_LOOKUP, "__array__")); arrayValueLookup.addChild(arrayIndexLookup); AST_Assignment assignmentTree = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), pLoopVariableName); assignmentTree.addChild(arrayValueLookup); statementList.addChild(assignmentTree); return statementList; }
private AST_VariableDeclaration declaration() { #if WRITE_DEBUG_INFO Console.WriteLine("declaration"); #endif Token typeName = match(Token.TokenType.BUILT_IN_TYPE_NAME); Token variableName = match(Token.TokenType.NAME); AST_VariableDeclaration declarationTree = new AST_VariableDeclaration( new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>", lookAhead(1).LineNr, lookAhead(1).LinePosition), ExternalFunctionCreator.GetReturnTypeFromString(typeName.getTokenString()), variableName.getTokenString()); return declarationTree; }
private AST parameter() { #if WRITE_DEBUG_INFO Console.WriteLine("parameter"); #endif AST parameterTree = new AST(new Token(Token.TokenType.PARAMETER, "<PARAMETER>", lookAhead(1).LineNr, lookAhead(1).LinePosition)); AST type = null; if(lookAheadType(1) == Token.TokenType.BUILT_IN_TYPE_NAME) { type = new AST(match(Token.TokenType.BUILT_IN_TYPE_NAME)); } else { type = new AST(new Token(Token.TokenType.BUILT_IN_TYPE_NAME, "var")); } AST name = new AST(match(Token.TokenType.NAME)); AST declaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<PARAMETER_DECLARATION>"), ExternalFunctionCreator.GetReturnTypeFromString(type.getTokenString()), name.getTokenString()); AST assigment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), name.getTokenString()); parameterTree.addChild(declaration); parameterTree.addChild(assigment); return parameterTree; }
private AST loop() { #if WRITE_DEBUG_INFO Console.WriteLine("loop"); #endif AST loopBlockStatements = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<LOOP_BLOCK_STATEMENTS>")); AST_LoopNode loopTree = new AST_LoopNode(match(Token.TokenType.LOOP)); bool isForeachLoop = false; if (lookAheadType(1) != Token.TokenType.NEW_LINE) { #if WRITE_DEBUG_INFO Console.WriteLine("foreach loop!"); #endif isForeachLoop = true; // __index__ AST_VariableDeclaration loopIndexDeclaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.NUMBER, "__index__"); loopBlockStatements.addChild(loopIndexDeclaration); AST_Assignment loopIndexAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__"); loopIndexAssignment.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "-1", new ReturnValue(-1.0f)))); loopBlockStatements.addChild(loopIndexAssignment); // match //match(Token.TokenType.PARANTHESIS_LEFT); AST arrayExpression = expression(); //match(Token.TokenType.PARANTHESIS_RIGHT); // __array__ (is a copy of the array to loop over) AST_VariableDeclaration loopArrayDeclaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.ARRAY, "__array__"); loopBlockStatements.addChild(loopArrayDeclaration); AST_Assignment loopArrayAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__array__"); if (arrayExpression != null) { loopArrayAssignment.addChild(arrayExpression); } else { throw new Error("Can't understand array expression in loop", Error.ErrorType.SYNTAX, loopArrayAssignment.getToken().LineNr, loopArrayAssignment.getToken().LinePosition); } loopBlockStatements.addChild(loopArrayAssignment); // __indexes__ (holds all the indexes in the array, since it works like a SortedDictionary) // __indexes = getIndexes(__array__) AST_VariableDeclaration indexesDeclaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.ARRAY, "__indexes__"); loopBlockStatements.addChild(indexesDeclaration); AST_FunctionCall getArrayIndexes = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "getIndexes")); AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>")); argumentList.addChild(new Token(Token.TokenType.NAME, "__array__")); getArrayIndexes.addChild(argumentList); AST_Assignment indexesAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__indexes__"); indexesAssignment.addChild(getArrayIndexes); loopBlockStatements.addChild(indexesAssignment); } else { #if WRITE_DEBUG_INFO Console.WriteLine("infinite loop!"); #endif } /* * loopParentTree * __index__-declaration * __array__-declaration & assigment * loop tree * loop body * foreach stuff * rest of statements * goto beginning of loop * * */ allowLineBreak(); AST loopBody = statementList(false); loopBody.addChild(new AST(new Token(Token.TokenType.GOTO_BEGINNING_OF_LOOP, "<GOTO_BEGINNING_OF_LOOP>"))); allowLineBreak(); match(Token.TokenType.BLOCK_END); if (isForeachLoop) { loopBody.addChildFirst(foreachStuff()); } loopTree.addChild(loopBody); loopBlockStatements.addChild(loopTree); AST_LoopBlockNode loopBlock = new AST_LoopBlockNode(new Token(Token.TokenType.LOOP_BLOCK, "<LOOP_BLOCK>")); loopBlock.addChild(loopBlockStatements); return(loopBlock); }
private AST loop() { #if WRITE_DEBUG_INFO Console.WriteLine("loop"); #endif AST loopBlockStatements = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<LOOP_BLOCK_STATEMENTS>")); AST_LoopNode loopTree = new AST_LoopNode(match(Token.TokenType.LOOP)); bool isForeachLoop = false; if(lookAheadType(1) != Token.TokenType.NEW_LINE) { #if WRITE_DEBUG_INFO Console.WriteLine("foreach loop!"); #endif isForeachLoop = true; // __index__ AST_VariableDeclaration loopIndexDeclaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.NUMBER, "__index__"); loopBlockStatements.addChild(loopIndexDeclaration); AST_Assignment loopIndexAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__"); loopIndexAssignment.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "-1", new ReturnValue(-1.0f)))); loopBlockStatements.addChild(loopIndexAssignment); // match //match(Token.TokenType.PARANTHESIS_LEFT); AST arrayExpression = expression(); //match(Token.TokenType.PARANTHESIS_RIGHT); // __array__ (is a copy of the array to loop over) AST_VariableDeclaration loopArrayDeclaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.ARRAY, "__array__"); loopBlockStatements.addChild(loopArrayDeclaration); AST_Assignment loopArrayAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__array__"); if(arrayExpression != null) { loopArrayAssignment.addChild(arrayExpression); } else { throw new Error("Can't understand array expression in loop", Error.ErrorType.SYNTAX, loopArrayAssignment.getToken().LineNr, loopArrayAssignment.getToken().LinePosition); } loopBlockStatements.addChild(loopArrayAssignment); // __indexes__ (holds all the indexes in the array, since it works like a SortedDictionary) // __indexes = getIndexes(__array__) AST_VariableDeclaration indexesDeclaration = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.ARRAY, "__indexes__"); loopBlockStatements.addChild(indexesDeclaration); AST_FunctionCall getArrayIndexes = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "getIndexes")); AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>")); argumentList.addChild(new Token(Token.TokenType.NAME, "__array__")); getArrayIndexes.addChild(argumentList); AST_Assignment indexesAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__indexes__"); indexesAssignment.addChild(getArrayIndexes); loopBlockStatements.addChild(indexesAssignment); } else { #if WRITE_DEBUG_INFO Console.WriteLine("infinite loop!"); #endif } /* * loopParentTree * __index__-declaration * __array__-declaration & assigment * loop tree * loop body * foreach stuff * rest of statements * goto beginning of loop * * */ allowLineBreak(); AST loopBody = statementList(false); loopBody.addChild(new AST(new Token(Token.TokenType.GOTO_BEGINNING_OF_LOOP, "<GOTO_BEGINNING_OF_LOOP>"))); allowLineBreak(); match(Token.TokenType.BLOCK_END); if(isForeachLoop) { loopBody.addChildFirst(foreachStuff()); } loopTree.addChild(loopBody); loopBlockStatements.addChild(loopTree); AST_LoopBlockNode loopBlock = new AST_LoopBlockNode(new Token(Token.TokenType.LOOP_BLOCK, "<LOOP_BLOCK>")); loopBlock.addChild(loopBlockStatements); return loopBlock; }