From 4143259eb3df16470dc2d93371e65e53d027243b Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Mon, 2 Aug 2021 18:35:10 -0700 Subject: [PATCH] Chapter 16.2 --- clox/src/compiler.c | 18 ++++++++++++++- clox/src/scanner.c | 29 +++++++++++++++++++++++ clox/src/scanner.h | 56 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/clox/src/compiler.c b/clox/src/compiler.c index 71961ef..2cc2ee4 100644 --- a/clox/src/compiler.c +++ b/clox/src/compiler.c @@ -4,4 +4,20 @@ #include "compiler.h" #include "scanner.h" -void compile(const char *source) { initScanner(source); } +void compile(const char *source) { + initScanner(source); + int line = -1; + for (;;) { + Token token = scanToken(); + if (token.line != line) { + printf("%4d ", token.line); + line = token.line; + } else { + printf(" | "); + } + printf("%2d '%.*s'\n", token.type, token.length, token.start); + + if (token.type == TOKEN_EOF) + break; + } +} diff --git a/clox/src/scanner.c b/clox/src/scanner.c index 2bcabb8..e125a99 100644 --- a/clox/src/scanner.c +++ b/clox/src/scanner.c @@ -17,3 +17,32 @@ void initScanner(const char *source) { scanner.current = source; scanner.line = 1; } + +static bool isAtEnd() { return *scanner.current == '\0'; } + +static Token makeToken(TokenType type) { + Token token; + token.type = type; + token.start = scanner.start; + token.length = (int)(scanner.current - scanner.start); + token.line = scanner.line; + return token; +} + +static Token errorToken(const char *message) { + Token token; + token.type = TOKEN_ERROR; + token.start = message; + token.length = (int)strlen(message); + token.line = scanner.line; + return token; +} + +Token scanToken() { + scanner.start = scanner.current; + + if (isAtEnd()) + return makeToken(TOKEN_EOF); + + return errorToken("Unexpected character."); +} diff --git a/clox/src/scanner.h b/clox/src/scanner.h index 3b8a261..6f42a9e 100644 --- a/clox/src/scanner.h +++ b/clox/src/scanner.h @@ -1,6 +1,62 @@ #ifndef SCANNER_H #define SCANNER_H +typedef enum { + /* Single-character tokens. */ + TOKEN_LEFT_PAREN, + TOKEN_RIGHT_PAREN, + TOKEN_LEFT_BRACE, + TOKEN_RIGHT_BRACE, + TOKEN_COMMA, + TOKEN_DOT, + TOKEN_MINUS, + TOKEN_PLUS, + TOKEN_SEMICOLON, + TOKEN_SLASH, + TOKEN_STAR, + /* One || two character tokens. */ + TOKEN_BANG, + TOKEN_BANG_EQUAL, + TOKEN_EQUAL, + TOKEN_EQUAL_EQUAL, + TOKEN_GREATER, + TOKEN_GREATER_EQUAL, + TOKEN_LESS, + TOKEN_LESS_EQUAL, + /* Literals. */ + TOKEN_IDENTIFIER, + TOKEN_STRING, + TOKEN_NUMBER, + /* Keywords. */ + TOKEN_AND, + TOKEN_CLASS, + TOKEN_ELSE, + TOKEN_FALSE, + TOKEN_FOR, + TOKEN_FUN, + TOKEN_IF, + TOKEN_NIL, + TOKEN_OR, + TOKEN_PRINT, + TOKEN_RETURN, + TOKEN_SUPER, + TOKEN_THIS, + TOKEN_TRUE, + TOKEN_VAR, + TOKEN_WHILE, + + TOKEN_ERROR, + TOKEN_EOF +} TokenType; + +typedef struct { + TokenType type; + const char *start; + int length; + int line; +} Token; + void initScanner(const char *source); +Token scanToken(); #endif