public static List<ExpressionArgument> BuildArgumentList(TokenList tokens) { List<ExpressionArgument> args = new List<ExpressionArgument>(); if (tokens.Current.TokenType != TokenType.GroupStart) return args; tokens.Advance(); // past the opening bracket while (tokens.Current.TokenType != TokenType.GroupEnd) { Token token = tokens.Current; IExpression expr = BuildExpression(tokens); if (tokens.Next == null) throw new TokenParserException("Oops, looks like someone didn't finish writing the script. It ended while I was putting together a list of arguments for a function call.", tokens.Peek(-2)); args.Add(new ExpressionArgument(expr, token)); token = tokens.Current; if (token.TokenType == TokenType.GroupEnd) continue; if (token.TokenType == TokenType.OtherSymbolic && token.Value == ",") { tokens.Advance(); if (tokens.Current.TokenType == TokenType.GroupEnd) throw new TokenParserException("There is a comma here to indicate that I should expect an argument following it, but instead there is a closing bracket.", tokens.Current); } else throw new TokenParserException("The list of function arguments needs to either end with a closing bracket, or have a comma to indicate that another argument is next.", token); } tokens.Advance(); return args; }
public static IInstruction BuildInstruction(TokenList tokens) { Token token = tokens.Current; // special case: if free text is found, create a "show" instruction to process it if (token.TokenType == TokenType.FreeText) return new ShowInstruction(BuildExpression(tokens)); // find the relevant creator/processor for the instruction if (token.TokenType == TokenType.Word || token.TokenType == TokenType.OtherSymbolic) { if (instructionCreators.ContainsKey(token.Value)) { IInstruction instruction = instructionCreators[token.Value].Create(); instruction.Build(tokens); return instruction; } } if (token.TokenType == TokenType.GroupStart || token.TokenType == TokenType.GroupEnd) throw new TokenParserException("Not sure why there is a bracket here.", token); if (token.Value == "end" && token.TokenType == TokenType.Word && tokens.Next == null) throw new TokenParserException("The end of the script has been reached prematurely.", tokens.Peek(-1)); if (expressionCreators.ContainsKey(token.Value)) throw new TokenParserException("\"" + token.Value + "\" can't stand by itself, as it is only designed to equate to a value. If you want to display the value, precede the keyword with a \"show\" instruction.", token); throw new TokenParserException("I have no idea what \"" + token.Value + "\" means.", token); }
public SprocketScript(string source, string descriptiveName, string scriptIdentificationString) { this.source = source; this.identifier = new ExecutionState.ScriptRecursionIdentifier(descriptiveName, scriptIdentificationString); TokenList tokens; try { tokens = Tokeniser.Extract(source); } catch (TokeniserException ex) { Token falseToken = new Token(source.Substring(ex.Position, 1), TokenType.FreeText, ex.Position); Token token = new Token(GetErrorHTML(ex.Message, falseToken, null), TokenType.FreeText, 0); tokens = new TokenList(new List<Token>(new Token[] { token })); instruction = new ShowInstruction(); instruction.Build(tokens); hasError = true; exception = ex; return; } try { instruction = TokenParser.BuildInstruction(tokens); } catch (TokenParserException ex) { Token token = new Token(GetErrorHTML(ex.Message, ex.Token, null), TokenType.FreeText, 0); tokens = new TokenList(new List<Token>(new Token[] { token })); instruction = new ShowInstruction(); instruction.Build(tokens); hasError = true; } }
public void Build(TokenList tokens) { // store the "list each [variable] in [list_expression]" tokens token = tokens.Current; Token eachToken = tokens.Peek(1); iteratorToken = tokens.Peek(2); Token inToken = tokens.Peek(3); listToken = tokens.Peek(4); // the first token of the list expression tokens.Advance(4); // make sure the "each" token is actually the word "each" if (eachToken.Value != "each" || eachToken.TokenType != TokenType.Word) throw new TokenParserException("\"list\" must be followed by the word \"each\".", eachToken); // validate the various tokens if (iteratorToken.TokenType != TokenType.Word) throw new TokenParserException("You must specify a word here that can be used as a variable, e.g. \"list each item in whatever\"", iteratorToken); if (TokenParser.IsReservedWord(iteratorToken.Value)) throw new TokenParserException("You can't use \"" + iteratorToken.Value + "\" as a variable name. It is the keyword for either an expression or an instruction.", iteratorToken); if (inToken.Value != "in" || inToken.TokenType != TokenType.Word) throw new TokenParserException("\"list each [something] must be followed by the word \"in\".", inToken); // build the list expression and the subsequent instruction list to loop through expr = TokenParser.BuildExpression(tokens); instructions = new InstructionList(); instructions.IsLoopBlock = true; instructions.Build(tokens); }
public void Build(TokenList tokens) { instructionListToken = tokens.Current; if(isStandardSection) tokens.Advance(); // only advance past the section token if // if the current token is the name of the instruction list, store it if (tokens.Current != null) if (tokens.Current.TokenType == TokenType.QuotedString) { name = tokens.Current.Value; tokens.Advance(); } // read each instruction, one by one until the end of the instruction list is reached while (tokens.Current != null) { // if we've reached a token indicating the end of this instruction block, advance past the ending token and return if ((!isLoopBlock && Token.IsEnd(tokens.Current)) || (isLoopBlock && Token.IsLoop(tokens.Current)) || (acceptELSEInPlaceOfEND && (Token.IsElse(tokens.Current) || Token.IsElseIf(tokens.Current)))) { // record the type of terminating token then advance past it switch (tokens.Current.Value) { case "else": terminator = TerminatorType.Else; break; case "elseif": terminator = TerminatorType.ElseIf; break; case "loop": terminator = TerminatorType.Loop; break; } tokens.Advance(); return; } list.Add(TokenParser.BuildInstruction(tokens)); } }
public void Build(TokenList tokens) { token = tokens.Current; // advance past the instruction token/symbol tokens.Advance(); // build the expression to evaluate and display at execution time expression = TokenParser.BuildExpression(tokens); }
public void PrepareExpression(TokenList tokens, Stack<int?> precedenceStack) { decimal n; if (decimal.TryParse(tokens.Current.Value, out n)) value = n; else value = null; tokens.Advance(); }
public void PrepareExpression(TokenList tokens, Stack<int?> precedenceStack) { Token token = tokens.Current; if (token.Value == "true") o = true; else o = false; tokens.Advance(); }
public static IExpression BuildBinaryExpression(TokenList tokens, IExpression leftExpr, Stack<int?> precedenceStack) { IBinaryExpressionCreator bxc = binaryExpressionCreators[tokens.Current.Value]; IBinaryExpression bx = bxc.Create(); bx.Left = leftExpr; precedenceStack.Push(bx.Precedence); bx.PrepareExpression(tokens, precedenceStack); precedenceStack.Pop(); return bx; }
public void Build(TokenList tokens) { //store the "while" token token = tokens.Current; tokens.Advance(); // build the expression to evaluate for each iteration through the loop expr = TokenParser.BuildExpression(tokens); // build the list of instructions to execute inside the loop list = new InstructionList(); list.IsLoopBlock = true; list.Build(tokens); }
public static bool NextHasGreaterPrecedence(int?thanPrecedence, TokenList tokens) { if (tokens.Current == null) { return(false); } Token token = tokens.Current; if (token.TokenType != TokenType.OtherSymbolic && token.TokenType != TokenType.Word) { return(false); } if (!binaryExpressionCreators.ContainsKey(token.Value)) { return(false); } if (thanPrecedence == null) // previous check must come before this one or we'll get a default true even if the operator (e.g. "@") isn't defined as a standard binary expression { return(true); } return(binaryExpressionCreators[token.Value].Precedence < thanPrecedence.Value); }
public static IExpression BuildGroupedExpression(TokenList tokens) { // advance past the opening bracket tokens.Advance(); //build the expression IExpression expr = BuildExpression(tokens); if (tokens.Current.TokenType != TokenType.GroupEnd) { string tokenval = tokens.Current.Value.Trim(); if (tokenval == "") { tokenval = "#"; } throw new TokenParserException("I think a closing bracket should be here. Did you forget to put it in?", new Token(tokenval, TokenType.Word, tokens.Current.Position)); } //advance past the closing bracket tokens.Advance(); return(expr); }
public void Build(TokenList tokens) { // read "set varname to" tokens.Advance(); varNameToken = tokens.Current; tokens.Advance(); Token toToken = tokens.Current; tokens.Advance(); // make sure the variable name token is a valid word/name for a variable if (varNameToken.TokenType != TokenType.Word) throw new TokenParserException("The \"set\" instruction must be followed by a word of your choice that will be subsequently used to hold some value.", tokens.Previous); if (TokenParser.IsReservedWord(varNameToken.Value)) throw new TokenParserException("You can't use \"" + varNameToken.Value + "\" as a variable name. It is the keyword for either an expression or an instruction.", varNameToken); // make sure the "to" token is actually the word "to" if (toToken.TokenType != TokenType.Word || toToken.Value != "to") throw new TokenParserException("The \"set\" instruction must be formatted like this: \"set something to some_expression\"", toToken); // build the expression that will be evaluated and assigned to the variable at run time expr = TokenParser.BuildExpression(tokens); }
public static IInstruction BuildInstruction(TokenList tokens) { Token token = tokens.Current; // special case: if free text is found, create a "show" instruction to process it if (token.TokenType == TokenType.FreeText) { return(new ShowInstruction(BuildExpression(tokens))); } // find the relevant creator/processor for the instruction if (token.TokenType == TokenType.Word || token.TokenType == TokenType.OtherSymbolic) { if (instructionCreators.ContainsKey(token.Value)) { IInstruction instruction = instructionCreators[token.Value].Create(); instruction.Build(tokens); return(instruction); } } if (token.TokenType == TokenType.GroupStart || token.TokenType == TokenType.GroupEnd) { throw new TokenParserException("Not sure why there is a bracket here.", token); } if (token.Value == "end" && token.TokenType == TokenType.Word && tokens.Next == null) { throw new TokenParserException("The end of the script has been reached prematurely.", tokens.Peek(-1)); } if (expressionCreators.ContainsKey(token.Value)) { throw new TokenParserException("\"" + token.Value + "\" can't stand by itself, as it is only designed to equate to a value. If you want to display the value, precede the keyword with a \"show\" instruction.", token); } throw new TokenParserException("I have no idea what \"" + token.Value + "\" means.", token); }
public void Build(TokenList tokens) { // store the "list each [variable] in [list_expression]" tokens token = tokens.Current; Token eachToken = tokens.Peek(1); iteratorToken = tokens.Peek(2); Token inToken = tokens.Peek(3); listToken = tokens.Peek(4); // the first token of the list expression tokens.Advance(4); // make sure the "each" token is actually the word "each" if (eachToken.Value != "each" || eachToken.TokenType != TokenType.Word) { throw new TokenParserException("\"list\" must be followed by the word \"each\".", eachToken); } // validate the various tokens if (iteratorToken.TokenType != TokenType.Word) { throw new TokenParserException("You must specify a word here that can be used as a variable, e.g. \"list each item in whatever\"", iteratorToken); } if (TokenParser.IsReservedWord(iteratorToken.Value)) { throw new TokenParserException("You can't use \"" + iteratorToken.Value + "\" as a variable name. It is the keyword for either an expression or an instruction.", iteratorToken); } if (inToken.Value != "in" || inToken.TokenType != TokenType.Word) { throw new TokenParserException("\"list each [something] must be followed by the word \"in\".", inToken); } // build the list expression and the subsequent instruction list to loop through expr = TokenParser.BuildExpression(tokens); instructions = new InstructionList(); instructions.IsLoopBlock = true; instructions.Build(tokens); }
public void Build(TokenList tokens) { instructionToken = tokens.Current; Token token = instructionToken; // advance past the instruction token/symbol tokens.Advance(); // build condition expression IExpression expr = TokenParser.BuildExpression(tokens); // build the instruction list that will execute if the expression evaluates to true InstructionList list = new InstructionList(); list.AcceptELSEInPlaceOfEND = true; list.Build(tokens); executionPaths.Add(new ExecutionPath(expr, list, token)); // if any elseif statements were used, build the execution paths for each one while (list.Terminator == InstructionList.TerminatorType.ElseIf) { token = tokens.Previous; expr = TokenParser.BuildExpression(tokens); list = new InstructionList(); list.AcceptELSEInPlaceOfEND = true; list.Build(tokens); executionPaths.Add(new ExecutionPath(expr, list, token)); } // if an else statement was used, build the instruction list that will execute if the expression evaluates to false if (list.Terminator == InstructionList.TerminatorType.Else) { token = tokens.Previous; list = new InstructionList(); list.AcceptELSEInPlaceOfEND = true; list.Build(tokens); executionPaths.Add(new ExecutionPath(null, list, token)); } }
public SprocketScript(string source, string descriptiveName, string scriptIdentificationString) { this.source = source; this.identifier = new ExecutionState.ScriptRecursionIdentifier(descriptiveName, scriptIdentificationString); TokenList tokens; try { tokens = Tokeniser.Extract(source); } catch (TokeniserException ex) { Token falseToken = new Token(source.Substring(ex.Position, 1), TokenType.FreeText, ex.Position); Token token = new Token(GetErrorHTML(ex.Message, falseToken, null), TokenType.FreeText, 0); tokens = new TokenList(new List <Token>(new Token[] { token })); instruction = new ShowInstruction(); instruction.Build(tokens); hasError = true; exception = ex; return; } try { instruction = TokenParser.BuildInstruction(tokens); } catch (TokenParserException ex) { Token token = new Token(GetErrorHTML(ex.Message, ex.Token, null), TokenType.FreeText, 0); tokens = new TokenList(new List <Token>(new Token[] { token })); instruction = new ShowInstruction(); instruction.Build(tokens); hasError = true; } }
public static IExpression BuildDeepExpression(IExpression expr, TokenList tokens) { if (tokens.Current.TokenType == TokenType.GroupStart) { Token t = tokens.Current; ArgumentsOfExpression ax = new ArgumentsOfExpression(expr, t, BuildArgumentList(tokens)); return(BuildDeepExpression(ax, tokens)); } else if (tokens.Current.TokenType == TokenType.PropertyDesignator) { tokens.Advance(); // past the property designator if (tokens.Current.TokenType != TokenType.Word) { throw new TokenParserException("This bit should be a word naming which property of thing thing before it that you are trying to evaluate.", tokens.Current); } PropertyOfExpression px = new PropertyOfExpression(expr, tokens.Current); tokens.Advance(); // past the property name return(BuildDeepExpression(px, tokens)); } else { return(expr); } }
public virtual void PrepareExpression(TokenList tokens, Stack<int?> precedenceStack) { token = tokens.Current; tokens.Advance(); right = TokenParser.BuildExpression(tokens, precedenceStack); }
public void PrepareExpression(TokenList tokens, Stack<int?> precedenceStack) { // get the token representing the variable name variableToken = tokens.Current; tokens.Advance(); }
public static IExpression BuildExpression(TokenList tokens) { Stack<int?> stack = new Stack<int?>(); stack.Push(null); return BuildExpression(tokens, stack); }
public void PrepareExpression(TokenList tokens, Stack<int?> precedenceStack) { if(tokens.Next.TokenType != TokenType.GroupStart) throw new TokenParserException("You must specify an argument representing the code name for the forum category you want to load.", tokens.Current); tokens.Advance(); }
public static IExpression BuildGroupedExpression(TokenList tokens) { // advance past the opening bracket tokens.Advance(); //build the expression IExpression expr = BuildExpression(tokens); if (tokens.Current.TokenType != TokenType.GroupEnd) { string tokenval = tokens.Current.Value.Trim(); if (tokenval == "") tokenval = "#"; throw new TokenParserException("I think a closing bracket should be here. Did you forget to put it in?", new Token(tokenval, TokenType.Word, tokens.Current.Position)); } //advance past the closing bracket tokens.Advance(); return expr; }
public void PrepareExpression(TokenList tokens, Stack <int?> precedenceStack) { // get the token representing the variable name variableToken = tokens.Current; tokens.Advance(); }
public StringExpression(TokenList tokens, Stack<int?> precedenceStack) { PrepareExpression(tokens, precedenceStack); }
public void PrepareExpression(TokenList tokens, Stack<int?> precedenceStack) { tokens.Advance(); expression = TokenParser.BuildExpression(tokens, precedenceStack); }
public static IExpression BuildDeepExpression(IExpression expr, TokenList tokens) { if (tokens.Current.TokenType == TokenType.GroupStart) { Token t = tokens.Current; ArgumentsOfExpression ax = new ArgumentsOfExpression(expr, t, BuildArgumentList(tokens)); return BuildDeepExpression(ax, tokens); } else if (tokens.Current.TokenType == TokenType.PropertyDesignator) { tokens.Advance(); // past the property designator if (tokens.Current.TokenType != TokenType.Word) throw new TokenParserException("This bit should be a word naming which property of thing thing before it that you are trying to evaluate.", tokens.Current); PropertyOfExpression px = new PropertyOfExpression(expr, tokens.Current); tokens.Advance(); // past the property name return BuildDeepExpression(px, tokens); } else return expr; }
public void PrepareExpression(TokenList tokens, Stack<int?> precedenceStack) { token = tokens.Current; tokens.Advance(); }
public void Build(TokenList tokens) { token = tokens.Current; // advance past the instruction token/symbol tokens.Advance(); }
public virtual void PrepareExpression(TokenList tokens, Stack <int?> precedenceStack) { token = tokens.Current; tokens.Advance(); right = TokenParser.BuildExpression(tokens, precedenceStack); }
public static bool NextHasGreaterPrecedence(int? thanPrecedence, TokenList tokens) { if (tokens.Current == null) return false; Token token = tokens.Current; if (token.TokenType != TokenType.OtherSymbolic && token.TokenType != TokenType.Word) return false; if (!binaryExpressionCreators.ContainsKey(token.Value)) return false; if (thanPrecedence == null) // previous check must come before this one or we'll get a default true even if the operator (e.g. "@") isn't defined as a standard binary expression return true; return binaryExpressionCreators[token.Value].Precedence < thanPrecedence.Value; }
public override void PrepareExpression(TokenList tokens, Stack<int?> precedenceStack) { base.PrepareExpression(tokens, precedenceStack); }
public NumericExpression(TokenList tokens, Stack<int?> precedenceStack) { PrepareExpression(tokens, precedenceStack); }
public NumericExpression(TokenList tokens, Stack <int?> precedenceStack) { PrepareExpression(tokens, precedenceStack); }
public static IExpression BuildExpression(TokenList tokens, Stack<int?> precedenceStack) { if (tokens.Current == null) throw new TokenParserException("The script seems to have ended prematurely. Shouldn't there be something here?", tokens.Peek(-2)); Token token = tokens.Current; IExpression expr = null; bool endGroupedExpression = false; switch (token.TokenType) { case TokenType.Number: expr = new NumericExpression(tokens, precedenceStack); break; case TokenType.QuotedString: expr = new StringExpression(tokens, precedenceStack); break; case TokenType.FreeText: expr = new StringExpression(tokens, precedenceStack); return expr; case TokenType.Word: if (expressionCreators.ContainsKey(token.Value)) { // find the appropriate handler for this keyword expr = expressionCreators[token.Value].Create(); } else // we don't recognise the word, so we can assume it's a variable and validate it at run-time { // don't allow instruction keywords to be used as variable names if (instructionCreators.ContainsKey(token.Value)) throw new TokenParserException("This word is the name of an instruction. You can't use it here in this context.", token); else expr = new VariableExpression(); } // if applicable, have the expression prepare itself according to its own rules if (expr is IFlexibleSyntaxExpression) ((IFlexibleSyntaxExpression)expr).PrepareExpression(tokens, precedenceStack); else // otherwise just advance to the next token tokens.Advance(); // chain together any properties and argument lists expr = BuildDeepExpression(expr, tokens); break; case TokenType.PropertyDesignator: // property designators are handled elsewhere. if we found one here, it's a parsing error. if (tokens.Previous.TokenType == TokenType.Word) throw new TokenParserException("This type of expression doesn't allow you to specify a property.", tokens.Next); throw new TokenParserException("You've got a property designator in a spot where it doesn't belong.", tokens.Next); case TokenType.GroupStart: expr = BuildGroupedExpression(tokens); break; case TokenType.GroupEnd: endGroupedExpression = true; break; default: throw new TokenParserException("This part of the script should equate to a value but instead I got \"" + token.Value + "\", which doesn't really mean anything in this context.", token); } if (!endGroupedExpression) { int? precedence = precedenceStack.Peek(); while (NextHasGreaterPrecedence(precedence, tokens)) expr = BuildBinaryExpression(tokens, expr, precedenceStack); } return expr; }
public static IExpression BuildExpression(TokenList tokens, Stack <int?> precedenceStack) { if (tokens.Current == null) { throw new TokenParserException("The script seems to have ended prematurely. Shouldn't there be something here?", tokens.Peek(-2)); } Token token = tokens.Current; IExpression expr = null; bool endGroupedExpression = false; switch (token.TokenType) { case TokenType.Number: expr = new NumericExpression(tokens, precedenceStack); break; case TokenType.QuotedString: expr = new StringExpression(tokens, precedenceStack); break; case TokenType.FreeText: expr = new StringExpression(tokens, precedenceStack); return(expr); case TokenType.Word: if (expressionCreators.ContainsKey(token.Value)) { // find the appropriate handler for this keyword expr = expressionCreators[token.Value].Create(); } else // we don't recognise the word, so we can assume it's a variable and validate it at run-time { // don't allow instruction keywords to be used as variable names if (instructionCreators.ContainsKey(token.Value)) { throw new TokenParserException("This word is the name of an instruction. You can't use it here in this context.", token); } else { expr = new VariableExpression(); } } // if applicable, have the expression prepare itself according to its own rules if (expr is IFlexibleSyntaxExpression) { ((IFlexibleSyntaxExpression)expr).PrepareExpression(tokens, precedenceStack); } else // otherwise just advance to the next token { tokens.Advance(); } // chain together any properties and argument lists expr = BuildDeepExpression(expr, tokens); break; case TokenType.PropertyDesignator: // property designators are handled elsewhere. if we found one here, it's a parsing error. if (tokens.Previous.TokenType == TokenType.Word) { throw new TokenParserException("This type of expression doesn't allow you to specify a property.", tokens.Next); } throw new TokenParserException("You've got a property designator in a spot where it doesn't belong.", tokens.Next); case TokenType.GroupStart: expr = BuildGroupedExpression(tokens); break; case TokenType.GroupEnd: endGroupedExpression = true; break; default: throw new TokenParserException("This part of the script should equate to a value but instead I got \"" + token.Value + "\", which doesn't really mean anything in this context.", token); } if (!endGroupedExpression) { int?precedence = precedenceStack.Peek(); while (NextHasGreaterPrecedence(precedence, tokens)) { expr = BuildBinaryExpression(tokens, expr, precedenceStack); } } return(expr); }
public void PrepareExpression(TokenList tokens, Stack <int?> precedenceStack) { tokens.Advance(); expression = TokenParser.BuildExpression(tokens, precedenceStack); }
public void PrepareExpression(TokenList tokens, Stack <int?> precedenceStack) { text = tokens.Current.Value; tokens.Advance(); }
public StringExpression(TokenList tokens, Stack <int?> precedenceStack) { PrepareExpression(tokens, precedenceStack); }
public override void PrepareExpression(TokenList tokens, Stack <int?> precedenceStack) { base.PrepareExpression(tokens, precedenceStack); }
public void Build(TokenList tokens) { token = tokens.Current; // advance past the instruction token/symbol tokens.Advance(); }