Compiling Expressions 17

This commit is contained in:
nazrin 2025-06-04 19:49:53 +00:00
parent 8fb449825d
commit 41404633da
18 changed files with 546 additions and 64 deletions

66
src/clox/parser.d Normal file
View 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);
}
}
}