fix if blocks, remove braces for blocks
This commit is contained in:
parent
5fc3f19c35
commit
67d586c789
@ -91,12 +91,11 @@ func (c *compiler) compileStatement(stmt parser.Statement) {
|
|||||||
c.compileExpression(s.Value)
|
c.compileExpression(s.Value)
|
||||||
c.emit(types.OpEcho, 0)
|
c.emit(types.OpEcho, 0)
|
||||||
|
|
||||||
|
// BlockStatement now should only be used for keyword blocks like if-then-else-end
|
||||||
case *parser.BlockStatement:
|
case *parser.BlockStatement:
|
||||||
c.enterScope()
|
|
||||||
for _, blockStmt := range s.Statements {
|
for _, blockStmt := range s.Statements {
|
||||||
c.compileStatement(blockStmt)
|
c.compileStatement(blockStmt)
|
||||||
}
|
}
|
||||||
c.exitScope()
|
|
||||||
|
|
||||||
case *parser.ExpressionStatement:
|
case *parser.ExpressionStatement:
|
||||||
c.compileExpression(s.Expression)
|
c.compileExpression(s.Expression)
|
||||||
|
@ -62,8 +62,9 @@ func New(l *lexer.Lexer) *Parser {
|
|||||||
p.registerPrefix(lexer.TokenMinus, p.parsePrefixExpression)
|
p.registerPrefix(lexer.TokenMinus, p.parsePrefixExpression)
|
||||||
p.registerPrefix(lexer.TokenLeftParen, p.parseGroupedExpression)
|
p.registerPrefix(lexer.TokenLeftParen, p.parseGroupedExpression)
|
||||||
p.registerPrefix(lexer.TokenIf, p.parseIfExpression)
|
p.registerPrefix(lexer.TokenIf, p.parseIfExpression)
|
||||||
p.registerPrefix(lexer.TokenElse, p.parseErrorToken)
|
p.registerPrefix(lexer.TokenElse, p.parseUnexpectedToken)
|
||||||
p.registerPrefix(lexer.TokenEnd, p.parseErrorToken)
|
p.registerPrefix(lexer.TokenEnd, p.parseUnexpectedToken)
|
||||||
|
p.registerPrefix(lexer.TokenThen, p.parseUnexpectedToken)
|
||||||
p.registerPrefix(lexer.TokenTrue, p.parseBooleanLiteral)
|
p.registerPrefix(lexer.TokenTrue, p.parseBooleanLiteral)
|
||||||
p.registerPrefix(lexer.TokenFalse, p.parseBooleanLiteral)
|
p.registerPrefix(lexer.TokenFalse, p.parseBooleanLiteral)
|
||||||
|
|
||||||
@ -167,8 +168,6 @@ func (p *Parser) parseStatement() Statement {
|
|||||||
return p.parseExpressionStatement()
|
return p.parseExpressionStatement()
|
||||||
case lexer.TokenEcho:
|
case lexer.TokenEcho:
|
||||||
return p.parseEchoStatement()
|
return p.parseEchoStatement()
|
||||||
case lexer.TokenLeftBrace:
|
|
||||||
return p.parseBlockStatement()
|
|
||||||
default:
|
default:
|
||||||
return p.parseExpressionStatement()
|
return p.parseExpressionStatement()
|
||||||
}
|
}
|
||||||
@ -337,7 +336,7 @@ func (p *Parser) parseNumberLiteral() Expression {
|
|||||||
|
|
||||||
func (p *Parser) parseTableLiteral() Expression {
|
func (p *Parser) parseTableLiteral() Expression {
|
||||||
table := &TableLiteral{
|
table := &TableLiteral{
|
||||||
Token: p.curToken,
|
Token: p.curToken, // This should be '{'
|
||||||
Pairs: make(map[Expression]Expression),
|
Pairs: make(map[Expression]Expression),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,54 +460,46 @@ func (p *Parser) parseIfExpression() Expression {
|
|||||||
|
|
||||||
// Expect 'then' after condition
|
// Expect 'then' after condition
|
||||||
if !p.expectPeek(lexer.TokenThen) {
|
if !p.expectPeek(lexer.TokenThen) {
|
||||||
p.errors = append(p.errors, "expected 'then' after if condition")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p.nextToken() // Skip 'then'
|
p.nextToken() // Skip 'then'
|
||||||
|
|
||||||
// Parse consequence (then block)
|
// Create a block statement for the consequence
|
||||||
if p.curTokenIs(lexer.TokenLeftBrace) {
|
consequence := &BlockStatement{Token: p.curToken}
|
||||||
expression.Consequence = p.parseBlockStatement()
|
consequence.Statements = []Statement{}
|
||||||
} else {
|
|
||||||
// For single statement without braces
|
// Parse statements until we hit 'else' or 'end'
|
||||||
stmt := &BlockStatement{Token: p.curToken}
|
for !p.curTokenIs(lexer.TokenElse) && !p.curTokenIs(lexer.TokenEnd) && !p.curTokenIs(lexer.TokenEOF) {
|
||||||
stmt.Statements = []Statement{p.parseStatement()}
|
stmt := p.parseStatement()
|
||||||
expression.Consequence = stmt
|
consequence.Statements = append(consequence.Statements, stmt)
|
||||||
|
p.nextToken()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expression.Consequence = consequence
|
||||||
|
|
||||||
// Check for 'else'
|
// Check for 'else'
|
||||||
if p.peekTokenIs(lexer.TokenElse) {
|
if p.curTokenIs(lexer.TokenElse) {
|
||||||
p.nextToken() // Move to 'else'
|
|
||||||
p.nextToken() // Skip 'else'
|
p.nextToken() // Skip 'else'
|
||||||
|
|
||||||
// Parse alternative (else block)
|
// Create a block statement for the alternative
|
||||||
if p.curTokenIs(lexer.TokenLeftBrace) {
|
alternative := &BlockStatement{Token: p.curToken}
|
||||||
expression.Alternative = p.parseBlockStatement()
|
alternative.Statements = []Statement{}
|
||||||
} else {
|
|
||||||
// For single statement without braces
|
|
||||||
stmt := &BlockStatement{Token: p.curToken}
|
|
||||||
stmt.Statements = []Statement{p.parseStatement()}
|
|
||||||
expression.Alternative = stmt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for 'end'
|
// Parse statements until we hit 'end'
|
||||||
if p.peekTokenIs(lexer.TokenEnd) {
|
for !p.curTokenIs(lexer.TokenEnd) && !p.curTokenIs(lexer.TokenEOF) {
|
||||||
p.nextToken() // Consume 'end'
|
stmt := p.parseStatement()
|
||||||
} else if !p.curTokenIs(lexer.TokenRightBrace) {
|
alternative.Statements = append(alternative.Statements, stmt)
|
||||||
// Missing 'end'
|
|
||||||
p.errors = append(p.errors, fmt.Sprintf("line %d: expected 'end' to close if expression",
|
|
||||||
p.curToken.Line))
|
|
||||||
|
|
||||||
// Skip tokens until we find something that could be a valid statement start
|
|
||||||
for !p.curTokenIs(lexer.TokenEOF) &&
|
|
||||||
!p.curTokenIs(lexer.TokenSemicolon) &&
|
|
||||||
!p.curTokenIs(lexer.TokenIdentifier) &&
|
|
||||||
!p.curTokenIs(lexer.TokenEcho) {
|
|
||||||
p.nextToken()
|
p.nextToken()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expression.Alternative = alternative
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should now be at the 'end' token
|
||||||
|
if !p.curTokenIs(lexer.TokenEnd) {
|
||||||
|
p.errors = append(p.errors, fmt.Sprintf("line %d: expected 'end' to close if expression",
|
||||||
|
p.curToken.Line))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,3 +511,9 @@ func (p *Parser) parseErrorToken() Expression {
|
|||||||
p.errors = append(p.errors, msg)
|
p.errors = append(p.errors, msg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Parser) parseUnexpectedToken() Expression {
|
||||||
|
p.errors = append(p.errors, fmt.Sprintf("line %d: unexpected token: %s",
|
||||||
|
p.curToken.Line, p.curToken.Value))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user