// retrieve a quoted sugar token (' ` , ,@) and advance our position private Token QuoteSugar() { TokenType type; builder.Clear(); switch (Character) { case '\'': type = TokenType.Quote; break; case '`': type = TokenType.QuasiQuote; break; case ',': type = TokenType.Unquote; break; default: throw TokenizerError.SyntaxError("tokenizer", "unexpected character", lastToken); } builder.Append((char)Character); NextChar(); if (Character == '@') { type = TokenType.UnquoteSplicing; NextChar(); builder.Append((char)Character); } return(DefineToken(type, builder.ToString( ))); }
public char GetCharacter( ) { Debug.Assert(type == TokenType.Character); if (value.Length == 3) { return(System.Convert.ToChar(value[2])); } else { var c = (char)0; if (NamedCharacter.NameToCharacter(value, out c)) { return(c); } throw TokenizerError.SyntaxError("get-character", "improperly formed char value", this); } }
// -- Parse value -------------------------------------------------------------------------------- public bool GetBool() { Debug.Assert(type == TokenType.Boolean); if (value == "#t") { return(true); } else if (value == "#f") { return(false); } else { throw TokenizerError.SyntaxError("get-bool", "improperly formed bool value", this); } }
public int GetInteger() { try { switch (type) { case TokenType.Integer: return(StringParser.GetInteger(value)); case TokenType.Heximal: return(StringParser.GetHexadecimal(value)); default: throw TokenizerError.SyntaxError("get-integer", "wrong token type", this); } } catch (System.Exception) { throw TokenizerError.SyntaxError("get-integer", "improperly formed int value", this); } }
// retrieve a string literal token and advance our position private Token StringLiteral() { builder.Clear(); NextChar(); var type = TokenType.String; var matchingQuotes = false; while (Character >= 0) { // if we get an escape, increment the position some more and map the escaped character to what it should be if (Character == '\\') { NextChar(); builder.Append(MapEscaped(Character)); NextChar(); continue; } // unescaped quote? We're done with this string. if (Character == '"') { NextChar(); matchingQuotes = true; break; } builder.Append((char)Character); NextChar(); } // we didn't get opening and closing quotes :( if (!matchingQuotes) { throw TokenizerError.SyntaxError("tokenizer", "unmatched quotes in string literal", lastToken); } return(DefineToken(type, builder.ToString())); }
// retrieve a number literal token (int or decimal) and advance our position private Token NumberLiteral() { var type = TokenType.Integer; builder.Clear(); while (Character >= 0 && IsNumericalPart(Character)) { // if we get a decimal we're no longer working with an integer if (Character == '.') { if (type == TokenType.Floating) { throw TokenizerError.SyntaxError("tokenizer", "error in numerical literal", lastToken); } type = TokenType.Floating; } builder.Append((char)Character); NextChar(); } return(DefineToken(type, builder.ToString( ))); }
// retrieve a vector literal marker, boolean token, or character literal token and advance our position private Token VectorOrBooleanOrChar() { builder.Clear(); var boolLiterals = new List <char> { 'F', 'f', 't', 'T' }; var nextc = reader.Peek(); if (boolLiterals.Contains((char)nextc)) { // boolean literal! builder.Append((char)Character); NextChar(); // skip # if (Character >= 0) { builder.Append((char)Character); NextChar(); // skip F,f,t,T } return(DefineToken(TokenType.Boolean, builder.ToString( ))); } else if (nextc == '(') { // vector literal! NextChar(); // skip # NextChar(); // skip ( return(DefineToken(TokenType.OpenVector, "(")); } else if (nextc == '\\') { // char literal! while (Character >= 0 && !IsWhitespace(Character)) { if (builder.Size < 3) { builder.Append((char)Character); NextChar(); } else { if (!IsEOF(Character) && IsSymbolPart(Character)) { builder.Append((char)Character); NextChar(); } else { break; } } } return(DefineToken(TokenType.Character, builder.ToString( ))); } else if (nextc == 'x') { builder.Append((char)Character); NextChar(); // skip # builder.Append((char)Character); NextChar(); // skip x // char literal! while (Character >= 0 && IsHeximalPart(Character)) { builder.Append((char)Character); NextChar(); } return(DefineToken(TokenType.Heximal, builder.ToString( ))); } //else if (nextc == '!') //{ // builder.Append((char)Character); // NextChar(); // skip # // builder.Append((char)Character); // NextChar(); // skip ! // // char literal! // while (Character >= 0 && IsSymbolPart(Character)) // { // builder.Append((char)Character); // NextChar(); // } // return DefineToken(TokenType.Symbol, builder.ToString()); //} else { throw TokenizerError.SyntaxError("tokenizer", "inside '#' but no matching characters to construct a token", lastToken); } }