diff options
author | David Robillard <d@drobilla.net> | 2010-12-07 23:26:35 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-12-07 23:26:35 +0000 |
commit | b38ff5a30986514a26bd800d113b40d6fcfef0db (patch) | |
tree | f36df58c0358a83c8439bf44ff9785049a16f2d3 /src/lex.cpp | |
parent | 375bed3c2e94f44fc3587f3b0cd036b97df8f72d (diff) | |
download | resp-b38ff5a30986514a26bd800d113b40d6fcfef0db.tar.gz resp-b38ff5a30986514a26bd800d113b40d6fcfef0db.tar.bz2 resp-b38ff5a30986514a26bd800d113b40d6fcfef0db.zip |
Rename 'lex' to the now more appropriate 'parse'.
git-svn-id: http://svn.drobilla.net/resp/resp@308 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/lex.cpp')
-rw-r--r-- | src/lex.cpp | 207 |
1 files changed, 0 insertions, 207 deletions
diff --git a/src/lex.cpp b/src/lex.cpp deleted file mode 100644 index 2ac838f..0000000 --- a/src/lex.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* Resp: A programming language - * Copyright (C) 2008-2009 David Robillard <dave@drobilla.net> - * - * Resp is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Resp is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General - * Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Resp. If not, see <http://www.gnu.org/licenses/>. - */ - -/** @file - * @brief Parsing (build an AST from text) - */ - -#include <stdio.h> -#include <stack> -#include "resp.hpp" - -using namespace std; - -static inline int -read_char(Cursor& cur, istream& in) -{ - int ch = in.get(); - switch (ch) { - case '\n': ++cur.line; cur.col = 0; break; - default: ++cur.col; - } - return ch; -} - -static inline void -skip_space(Cursor& cur, istream& in) -{ - while (isspace(in.peek())) - read_char(cur, in); -} - -static inline void -eat_char(Cursor& cur, istream& in, const char character) -{ - const char c = read_char(cur, in); - assert(c == character); - return; -} - -static AST* -read_string(Cursor& cur, istream& in) -{ - string str; - char c; - Cursor loc = cur; - eat_char(cur, in, '"'); - while ((c = read_char(cur, in)) != '"') { - if (c == '\\') { // string escape - switch (c = read_char(cur, in)) { - case '"': - str.push_back('"'); - break; - case '\\': - str.push_back('\\'); - break; - default: - cin.putback(c); - throw Error(cur, string("unknown string escape `\\") + (char)c + "'"); - } - } else { // any other character - str.push_back(c); - } - } - return new AString(loc, str); -} - -static AST* -read_line_comment(Cursor& cur, istream& in) -{ - char c; - while ((c = read_char(cur, in)) != '\n') {} - return NULL; -} - -static AST* -read_list(PEnv& penv, Cursor& cur, istream& in) -{ - List<ATuple, AST> list; - - eat_char(cur, in, '('); - while (true) { - skip_space(cur, in); - if (in.peek() == ')') { - eat_char(cur, in, ')'); - return list.head; - } - - list.push_back(read_expression(penv, cur, in)); - } - assert(false); -} - -static AST* -read_special(Cursor& cur, istream& in) -{ - eat_char(cur, in, '#'); - switch (in.peek()) { - case '|': - while (!(read_char(cur, in) == '|' && read_char(cur, in) == '#')) {} - return NULL; - case 't': - eat_char(cur, in, 't'); - return new ALiteral<bool>(T_BOOL, true, cur); - case 'f': - return new ALiteral<bool>(T_BOOL, false, cur); - default: - throw Error(cur, (format("unknown special lexeme `%1%'") % in.peek()).str()); - } - assert(false); - return NULL; -} - -static AST* -read_number(Cursor& cur, istream& in) -{ - string str; - char c; - Cursor loc = cur; - while ((c = in.peek()) != EOF) { - if (isdigit(c) || c == '.') - str += read_char(cur, in); - else - break; - } - - if (str.find('.') == string::npos) - return new ALiteral<int32_t>(T_INT32, strtol(str.c_str(), NULL, 10), loc); - else - return new ALiteral<float>(T_FLOAT, strtod(str.c_str(), NULL), loc); -} - -static AST* -read_symbol(PEnv& penv, Cursor& cur, istream& in) -{ - string str; - char c; - Cursor loc = cur; - while ((c = in.peek()) != EOF) { - if (!isspace(c) && c != ')' && c != '(' && c != EOF && c != -1) { - str += read_char(cur, in); - } else { - break; - } - } - - return penv.sym(str); -} - -/// Read an expression from @a in -AST* -read_expression(PEnv& penv, Cursor& cur, istream& in) -{ - while (!cin.eof()) { - skip_space(cur, in); - const char c = in.peek(); - switch (c) { - case EOF: - return NULL; - case ';': - read_line_comment(cur, in); - break; - case '"': - return read_string(cur, in); - case '(': - return read_list(penv, cur, in); - case ')': - throw Error(cur, "unexpected `)'"); - case '#': - { - AST* ret = read_special(cur, in); - if (ret) - return ret; - break; - } - case '-': - case '+': - read_char(cur, in); - if (isdigit(in.peek())) { - in.putback(c); - return read_number(cur, in); - } else { - in.putback(c); - return read_symbol(penv, cur, in); - } - default: - if (isdigit(c)) - return read_number(cur, in); - else - return read_symbol(penv, cur, in); - } - } - return NULL; -} |