Compiling Expressions 17
This commit is contained in:
parent
8fb449825d
commit
41404633da
18 changed files with 546 additions and 64 deletions
66
src/clox/parser.d
Normal file
66
src/clox/parser.d
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
module clox.parser;
|
||||
|
||||
import clox.compiler;
|
||||
import clox.value;
|
||||
import clox.scanner;
|
||||
import clox.parserules;
|
||||
|
||||
struct Parser{
|
||||
Compiler* compiler;
|
||||
Token current, previous;
|
||||
bool hadError, panicMode;
|
||||
void errorAtCurrent(string message){
|
||||
errorAt(current, message);
|
||||
}
|
||||
void error(string message){
|
||||
errorAt(previous, message);
|
||||
}
|
||||
void errorAt(in ref Token token, string message){
|
||||
import core.stdc.stdio;
|
||||
if(panicMode)
|
||||
return;
|
||||
panicMode = true;
|
||||
fprintf(stderr, "[line %d] Error", token.line);
|
||||
if(token.type == Token.Type.EOF){
|
||||
fprintf(stderr, " at end");
|
||||
} else if(token.type != Token.Type.Error){
|
||||
fprintf(stderr, " at '%.*s'", cast(int)token.lexeme.length, token.lexeme.ptr);
|
||||
}
|
||||
fprintf(stderr, ": %.*s\n", cast(int)message.length, message.ptr);
|
||||
hadError = true;
|
||||
}
|
||||
auto consume(Token.Type type, string msg){
|
||||
if(current.type == type){
|
||||
advance();
|
||||
return;
|
||||
}
|
||||
errorAtCurrent(msg);
|
||||
}
|
||||
void advance(){
|
||||
previous = current;
|
||||
while(true){
|
||||
current = compiler.scanner.scan();
|
||||
if(current.type != Token.Type.Error)
|
||||
break;
|
||||
errorAtCurrent(current.lexeme);
|
||||
}
|
||||
}
|
||||
|
||||
void expression(){
|
||||
parsePrecedence(Precedence.Assignment);
|
||||
}
|
||||
void parsePrecedence(Precedence precedence){
|
||||
advance();
|
||||
ParseFn prefixRule = ParseRule.get(previous.type).prefix;
|
||||
if(prefixRule == null){
|
||||
error("Expect expression.");
|
||||
return;
|
||||
}
|
||||
prefixRule(compiler);
|
||||
while(precedence <= ParseRule.get(current.type).precedence){
|
||||
advance();
|
||||
ParseFn infixRule = ParseRule.get(previous.type).infix;
|
||||
infixRule(compiler);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue