Classes 12
This commit is contained in:
parent
52a7b73a9e
commit
d8ac625429
18 changed files with 417 additions and 186 deletions
|
|
@ -83,7 +83,7 @@ class Parser{
|
|||
private Stmt printStatement(){
|
||||
version(LoxPrintMultiple){
|
||||
Expr[] values;
|
||||
do {
|
||||
if(!check(TokenType.SEMICOLON)) do {
|
||||
values ~= expression();
|
||||
} while(match(TokenType.COMMA));
|
||||
consume(TokenType.SEMICOLON, "Expect ';' after values.");
|
||||
|
|
@ -144,7 +144,7 @@ class Parser{
|
|||
else
|
||||
initialiser = expressionStatement();
|
||||
|
||||
Expr condition = check(TokenType.SEMICOLON) ? new Expr.Literal(TValue.bln(true)) : expression();
|
||||
Expr condition = check(TokenType.SEMICOLON) ? new Expr.Literal(new LoxBool(true)) : expression();
|
||||
consume(TokenType.SEMICOLON, "Expect ';' after loop condition.");
|
||||
|
||||
Expr increment;
|
||||
|
|
@ -197,8 +197,11 @@ class Parser{
|
|||
if(match(TokenType.EQUAL)){
|
||||
Token equals = previous();
|
||||
Expr value = assignment();
|
||||
if(auto v = cast(Expr.Variable)expr)
|
||||
if(auto v = cast(Expr.Variable)expr){
|
||||
return new Expr.Assign(v.name, value);
|
||||
} else if(auto get = cast(Expr.Get)expr){
|
||||
return new Expr.Set(get.object, get.name, value);
|
||||
}
|
||||
error(equals, "Invalid assignment target.");
|
||||
}
|
||||
return expr;
|
||||
|
|
@ -280,10 +283,14 @@ class Parser{
|
|||
}
|
||||
Expr expr = primary();
|
||||
while(true){
|
||||
if(match(TokenType.LEFT_PAREN))
|
||||
if(match(TokenType.LEFT_PAREN)){
|
||||
expr = finishCall(expr);
|
||||
else
|
||||
} else if(match(TokenType.DOT)){
|
||||
Token name = consume(TokenType.IDENTIFIER, "Expect property name after '.'.");
|
||||
expr = new Expr.Get(expr, name);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
|
@ -291,13 +298,15 @@ class Parser{
|
|||
if(match(TokenType.IDENTIFIER))
|
||||
return new Expr.Variable(previous());
|
||||
if(match(TokenType.FALSE))
|
||||
return new Expr.Literal(TValue.bln(false));
|
||||
return new Expr.Literal(new LoxBool(false));
|
||||
if(match(TokenType.TRUE))
|
||||
return new Expr.Literal(TValue.bln(true));
|
||||
return new Expr.Literal(new LoxBool(true));
|
||||
if(match(TokenType.NIL))
|
||||
return new Expr.Literal(tvalueNil);
|
||||
return new Expr.Literal(new LoxNil());
|
||||
if(match(TokenType.NUMBER, TokenType.STRING))
|
||||
return new Expr.Literal(previous().literal);
|
||||
if(match(TokenType.THIS))
|
||||
return new Expr.This(previous());
|
||||
if(match(TokenType.LEFT_PAREN)){
|
||||
Expr expr = expression();
|
||||
consume(TokenType.RIGHT_PAREN, "Expect ')' after expression.");
|
||||
|
|
@ -313,12 +322,23 @@ class Parser{
|
|||
consume(TokenType.SEMICOLON, "Expect ';' after variable declaration.");
|
||||
return new Stmt.Var(name, initialiser);
|
||||
}
|
||||
private Stmt classDeclaration() {
|
||||
Token name = consume(TokenType.IDENTIFIER, "Expect class name.");
|
||||
consume(TokenType.LEFT_BRACE, "Expect '{' before class body.");
|
||||
Stmt.Function[] methods;
|
||||
while(!check(TokenType.RIGHT_BRACE) && !isAtEnd)
|
||||
methods ~= fun("method");
|
||||
consume(TokenType.RIGHT_BRACE, "Expect '}' after class body.");
|
||||
return new Stmt.Class(name, methods);
|
||||
}
|
||||
private Stmt declaration(){
|
||||
try {
|
||||
if(match(TokenType.FUN))
|
||||
return fun("function");
|
||||
if(match(TokenType.VAR))
|
||||
return varDeclaration();
|
||||
if(match(TokenType.FUN))
|
||||
return fun("function");
|
||||
if(match(TokenType.CLASS))
|
||||
return classDeclaration();
|
||||
return statement();
|
||||
} catch(ParseError error){
|
||||
synchronise();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue