/// <summary> /// Process an array of tokens as an expression and append the instructions to a list. /// </summary> /// <param name="tokens"></param> protected void ProcessExpression(string[] tokens) { ExpressionBuilder eb = new ExpressionBuilder(tokens, currentLine); eb.Parse(); Instruction[] expression_instructions = (Instruction[])eb.GetResult(); foreach (Instruction instruction in expression_instructions) { Instructions.Add(instruction); } }
/// <summary> /// Parse a function call using the given loading instruction. /// </summary> /// <param name="load"></param> private void ParseFuncCall(Instruction load) { int parenthDepth = 1; DmlSyntaxError badCall = new DmlSyntaxError( "Invalid syntax; mismatched brackets for function call."); var subExpressions = new List <List <string> >(); var currentExpression = new List <string>(); while (true) { Advance(exception: badCall); if (DmlTokens.IsMatch(CurrentToken, DmlTokens.LPAR)) { parenthDepth++; } else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.RPAR)) { parenthDepth--; } else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.COMMA) && parenthDepth == 1) { subExpressions.Add(currentExpression); currentExpression = new List <string>(); continue; } if (parenthDepth == 0) { if (currentExpression.Count > 0) { subExpressions.Add(currentExpression); } break; } currentExpression.Add(CurrentToken); } ExpressionBuilder eb; foreach (var subExpression in subExpressions) { eb = new ExpressionBuilder(subExpression.ToArray(), currentLine); eb.Parse(); foreach (Instruction instruction in (Instruction[])(eb.GetResult())) { instructions.Add(instruction); } } instructions.Add(load); instructions.Add(new CallFunction(subExpressions.Count)); }
/// <summary> /// Process a generic `Range` statement. /// </summary> /// <param name="nsType"></param> protected void ProcessRange() { DmlSyntaxError badRange = DmlSyntaxError.BadRangeStatement(); Advance(exception: badRange); // Parse the loop variable. if (!DmlTokens.IsName(CurrentToken)) { throw badRange; } string loopVariable = CurrentToken; Advance(exception: badRange); // Parse the range start. List <String> startTokens; try { startTokens = new List <String>(GetUntil(DmlTokens.ELLIPSES)); } catch (ParserError) { throw badRange; } ExpressionBuilder startExpressionBuilder = new ExpressionBuilder(startTokens.ToArray(), currentLine); startExpressionBuilder.Parse(); var startInstructions = (Instruction[])startExpressionBuilder.GetResult(); Advance(exception: badRange); // Parse the range end and range step. List <String> endTokens; try { endTokens = new List <String>(GetUntil(DmlTokens.LANGLE)); } catch (ParserError) { throw badRange; } // Check if the range operator is extended to include a step. int stepIndex = endTokens.IndexOf(DmlTokens.TRANSOP); List <String> stepTokens; if (stepIndex == endTokens.Count - 1) { throw badRange; } else if (stepIndex != -1) { stepTokens = new List <string>(endTokens.Skip(stepIndex + 1)); endTokens = new List <string>(endTokens.Take(stepIndex)); } else { // Default step size is 1. stepTokens = new List <String>() { "1" } }; ExpressionBuilder endExpressionBuilder = new ExpressionBuilder(endTokens.ToArray(), currentLine); ExpressionBuilder stepExpressionBuilder = new ExpressionBuilder(stepTokens.ToArray(), currentLine); endExpressionBuilder.Parse(); stepExpressionBuilder.Parse(); var endInstructions = (Instruction[])endExpressionBuilder.GetResult(); var stepInstructions = (Instruction[])stepExpressionBuilder.GetResult(); /* * if (DmlParser.IsSimpleConstant(startInstructions) && * DmlParser.IsSimpleConstant(endInstructions) && * DmlParser.IsSimpleConstant(stepInstructions) * ) * { * double start, end, step; * try * { * start = (double)(new CodeBlock(startInstructions).Evaluate(null, null).Value); * end = (double)(new CodeBlock(endInstructions).Evaluate(null, null).Value); * step = (double)(new CodeBlock(stepInstructions).Evaluate(null, null).Value); * InlineRange(loopVariable, start, end, step); * } * catch (InvalidCastException) * { * // InlineRange can only handle double values. * ComplexRange(loopVariable, startInstructions, endInstructions, stepInstructions); * } * } * else */ // FIXME: // So there's a problem with InlineRange. If there are jump statements inside the code within // the Range block, the labels and the jumps will get repeated, so all jumps lead to the same // spot, which leads to infinite recursion. // Not sure why but sometimes the current token is set to the left namespace delimiter, // and sometimes its set to the first token after the delimiter. It doesn't seem to be // dependent on the presense of the step operator \> either. For now this works. if (DmlTokens.IsMatch(CurrentToken, DmlTokens.LANGLE)) { Advance(); } ComplexRange(loopVariable, startInstructions, endInstructions, stepInstructions); } }
/// <summary> /// Parse a function call using the given loading instruction. /// </summary> /// <param name="load"></param> private void ParseFuncCall(Instruction load) { int parenthDepth = 1; DmlSyntaxError badCall = new DmlSyntaxError( "Invalid syntax; mismatched brackets for function call."); var subExpressions = new List<List<string>>(); var currentExpression = new List<string>(); while (true) { Advance(exception: badCall); if (DmlTokens.IsMatch(CurrentToken, DmlTokens.LPAR)) parenthDepth++; else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.RPAR)) parenthDepth--; else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.COMMA) && parenthDepth == 1) { subExpressions.Add(currentExpression); currentExpression = new List<string>(); continue; } if (parenthDepth == 0) { if (currentExpression.Count > 0) subExpressions.Add(currentExpression); break; } currentExpression.Add(CurrentToken); } ExpressionBuilder eb; foreach (var subExpression in subExpressions) { eb = new ExpressionBuilder(subExpression.ToArray(), currentLine); eb.Parse(); foreach (Instruction instruction in (Instruction[])(eb.GetResult())) instructions.Add(instruction); } instructions.Add(load); instructions.Add(new CallFunction(subExpressions.Count)); }
/// <summary> /// Process a generic `Range` statement. /// </summary> /// <param name="nsType"></param> protected void ProcessRange() { DmlSyntaxError badRange = DmlSyntaxError.BadRangeStatement(); Advance(exception: badRange); // Parse the loop variable. if (!DmlTokens.IsName(CurrentToken)) throw badRange; string loopVariable = CurrentToken; Advance(exception: badRange); // Parse the range start. List<String> startTokens; try { startTokens = new List<String>(GetUntil(DmlTokens.ELLIPSES)); } catch (ParserError) { throw badRange; } ExpressionBuilder startExpressionBuilder = new ExpressionBuilder(startTokens.ToArray(), currentLine); startExpressionBuilder.Parse(); var startInstructions = (Instruction[])startExpressionBuilder.GetResult(); Advance(exception: badRange); // Parse the range end and range step. List<String> endTokens; try { endTokens = new List<String>(GetUntil(DmlTokens.LANGLE)); } catch (ParserError) { throw badRange; } // Check if the range operator is extended to include a step. int stepIndex = endTokens.IndexOf(DmlTokens.TRANSOP); List<String> stepTokens; if (stepIndex == endTokens.Count - 1) throw badRange; else if (stepIndex != -1) { stepTokens = new List<string>(endTokens.Skip(stepIndex + 1)); endTokens = new List<string>(endTokens.Take(stepIndex)); } else // Default step size is 1. stepTokens = new List<String>() { "1" }; ExpressionBuilder endExpressionBuilder = new ExpressionBuilder(endTokens.ToArray(), currentLine); ExpressionBuilder stepExpressionBuilder = new ExpressionBuilder(stepTokens.ToArray(), currentLine); endExpressionBuilder.Parse(); stepExpressionBuilder.Parse(); var endInstructions = (Instruction[])endExpressionBuilder.GetResult(); var stepInstructions = (Instruction[])stepExpressionBuilder.GetResult(); /* if (DmlParser.IsSimpleConstant(startInstructions) && DmlParser.IsSimpleConstant(endInstructions) && DmlParser.IsSimpleConstant(stepInstructions) ) { double start, end, step; try { start = (double)(new CodeBlock(startInstructions).Evaluate(null, null).Value); end = (double)(new CodeBlock(endInstructions).Evaluate(null, null).Value); step = (double)(new CodeBlock(stepInstructions).Evaluate(null, null).Value); InlineRange(loopVariable, start, end, step); } catch (InvalidCastException) { // InlineRange can only handle double values. ComplexRange(loopVariable, startInstructions, endInstructions, stepInstructions); } } else */ // FIXME: // So there's a problem with InlineRange. If there are jump statements inside the code within // the Range block, the labels and the jumps will get repeated, so all jumps lead to the same // spot, which leads to infinite recursion. // Not sure why but sometimes the current token is set to the left namespace delimiter, // and sometimes its set to the first token after the delimiter. It doesn't seem to be // dependent on the presense of the step operator \> either. For now this works. if (DmlTokens.IsMatch(CurrentToken, DmlTokens.LANGLE)) Advance(); ComplexRange(loopVariable, startInstructions, endInstructions, stepInstructions); }
/// <summary> /// Process an array of tokens as an expression and append the instructions to a list. /// </summary> /// <param name="tokens"></param> protected void ProcessExpression(string[] tokens) { ExpressionBuilder eb = new ExpressionBuilder(tokens, currentLine); eb.Parse(); Instruction[] expression_instructions = (Instruction[])eb.GetResult(); foreach (Instruction instruction in expression_instructions) Instructions.Add(instruction); }