aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/lexer.h14
-rw-r--r--src/lexer.cc99
2 files changed, 112 insertions, 1 deletions
diff --git a/include/lexer.h b/include/lexer.h
index 4b5f180..c8cd1a3 100644
--- a/include/lexer.h
+++ b/include/lexer.h
@@ -10,6 +10,20 @@ private:
char *m_script;
List *m_tokens;
+private:
+ size_t m_start;
+ size_t m_current;
+ size_t m_end;
+ size_t m_line;
+
+private:
+ bool at_end(void);
+ char advance(void);
+ char peek(void);
+ bool match(char c);
+ void add_token(token_type_e type);
+ void scan_token(void);
+
public:
void init(char *script);
List *scan(void);
diff --git a/src/lexer.cc b/src/lexer.cc
index 5a6f7b9..2ccc349 100644
--- a/src/lexer.cc
+++ b/src/lexer.cc
@@ -13,16 +13,25 @@ Lexer::init(char *script)
m_tokens = (List *) calloc(1, sizeof(List));
m_tokens->init(sizeof(Token));
+
+ m_start = 0;
+ m_current = 0;
+ m_end = strlen(m_script);
+ m_line = 1;
}
List *
Lexer::scan(void)
{
- printf("%s\n", m_script);
+ while (!at_end()) {
+ m_start = m_current;
+ scan_token();
+ }
Token token_eof;
token_eof.init(EOFF, "EOF", 2);
m_tokens->add(&token_eof);
+ token_eof.clean();
return m_tokens;
}
@@ -38,3 +47,91 @@ Lexer::clean(void)
m_tokens->clean();
free(m_script);
}
+
+bool
+Lexer::at_end(void)
+{
+ return m_current > m_end;
+}
+
+char
+Lexer::advance(void)
+{
+ return m_script[m_current++];
+}
+
+char
+Lexer::peek(void)
+{
+ return m_script[m_current];
+}
+
+bool
+Lexer::match(char c)
+{
+ if (at_end())
+ return false;
+ if (m_script[m_current] != c)
+ return false;
+
+ m_current++;
+ return true;
+}
+
+void
+Lexer::add_token(token_type_e type)
+{
+ size_t token_size = m_current - m_start;
+ if (token_size == 0)
+ token_size++;
+
+ char *text = (char *) malloc(sizeof(char) * token_size);
+ strncpy(text, m_script + m_start, token_size);
+
+ Token token;
+ token.init(type, text, m_line);
+ m_tokens->add(&token);
+ token.clean();
+}
+
+void
+Lexer::scan_token(void)
+{
+ char c = advance();
+ switch (c) {
+ case '(':
+ add_token(LEFT_PAREN);
+ break;
+ case ')':
+ add_token(RIGHT_PAREN);
+ break;
+ case '{':
+ add_token(LEFT_BRACE);
+ break;
+ case '}':
+ add_token(RIGHT_BRACE);
+ break;
+ case ',':
+ add_token(COMMA);
+ break;
+ case '.':
+ add_token(DOT);
+ break;
+ case '-':
+ add_token(MINUS);
+ break;
+ case '+':
+ add_token(PLUS);
+ break;
+ case ';':
+ add_token(SEMICOLON);
+ break;
+ case '*':
+ add_token(STAR);
+ break;
+
+ case '\n':
+ m_line++;
+ break;
+ }
+}