private static bool DoSubDefinition(Token <TokenType> first, Interpreter interpreter, SourceReader reader, State state) { bool meta = reader.Take(TokenType.Question); reader.Read(TokenType.LeftSquare); var parameters = new List <Tuple <string, ParamFlags> >(); var tName = reader.Read(TokenType.Text, "subroutine name"); if (!Util.ValidateName(tName.Value)) { throw new RantException(reader.Source, tName, "Invalid subroutine name: '" + tName.Value + "'"); } if (!reader.Take(TokenType.Colon)) { reader.Read(TokenType.RightSquare); } else { while (true) { bool isTokens = reader.Take(TokenType.At); parameters.Add(Tuple.Create(reader.Read(TokenType.Text, "parameter name").Value, isTokens ? ParamFlags.Code : ParamFlags.None)); if (reader.Take(TokenType.RightSquare, false)) { break; } reader.Read(TokenType.Semicolon); } } reader.SkipSpace(); reader.Read(TokenType.Colon); var body = reader.ReadToScopeClose(TokenType.LeftSquare, TokenType.RightSquare, BracketPairs.All).ToArray(); if (meta) { interpreter.PushState(State.CreateDerivedDistinct(reader.Source, body, interpreter)); state.AddPreBlueprint(new FunctionBlueprint(interpreter, _ => { _.Engine.Subroutines.Define(tName.Value, Subroutine.FromString(tName.Value, _.PopResultString(), parameters.ToArray())); return(false); })); } else { interpreter.Engine.Subroutines.Define(tName.Value, Subroutine.FromTokens(tName.Value, reader.Source, body, parameters.ToArray())); } return(meta); }
private static bool DoTag(Interpreter interpreter, SourceReader reader, State state) { reader.Read(TokenType.LeftSquare); var name = reader.ReadToken(); // Check if metapattern if (name.Identifier == TokenType.Question) { state.AddPreBlueprint(new MetapatternBlueprint(interpreter)); interpreter.PushState(State.CreateDerivedDistinct(reader.Source, reader.ReadToScopeClose(TokenType.LeftSquare, TokenType.RightSquare, BracketPairs.All), interpreter)); return(true); } // Check if replacer if (name.Identifier == TokenType.Regex) { return(DoReplacer(name, interpreter, reader, state)); } if (name.Identifier == TokenType.Dollar) { return(reader.IsNext(TokenType.Text) ? DoSubCall(name, interpreter, reader, state) : DoSubDefinition(name, interpreter, reader, state)); } if (!Util.ValidateName(name.Value.Trim())) { throw new RantException(reader.Source, name, "Invalid tag name '" + name.Value + "'"); } bool none = false; if (!reader.Take(TokenType.Colon)) { if (!reader.Take(TokenType.RightSquare)) { throw new RantException(reader.Source, name, "Expected ':' or ']' after tag name."); } none = true; } if (none) { state.AddPreBlueprint(new TagBlueprint(interpreter, reader.Source, name)); } else { var items = reader.ReadItemsToClosureTrimmed(TokenType.LeftSquare, TokenType.RightSquare, TokenType.Semicolon, BracketPairs.All).ToArray(); state.AddPreBlueprint(new TagBlueprint(interpreter, reader.Source, name, items)); } return(true); }
private static bool DoMath(Interpreter interpreter, SourceReader reader, State state) { reader.Read(TokenType.LeftParen); bool isStatement = reader.Take(TokenType.At); var tokens = reader.ReadToScopeClose(TokenType.LeftParen, TokenType.RightParen, BracketPairs.All); interpreter.PushState(State.CreateDerivedDistinct(reader.Source, tokens, interpreter)); state.AddPreBlueprint(new FunctionBlueprint(interpreter, _ => { var v = Parser.Calculate(_, _.PopResultString()); if (!isStatement) { _.Print(_.FormatNumber(v)); } return(false); })); return(true); }