simple while
This commit is contained in:
		
							parent
							
								
									8adfb71887
								
							
						
					
					
						commit
						6bb2408269
					
				
					 5 changed files with 54 additions and 5 deletions
				
			
		|  | @ -117,3 +117,11 @@ func (as *AstStringer) visitIfStmt(i *IfStmt) { | |||
| func (as *AstStringer) visitEnvStmt(e *EnvStmt) { | ||||
| 	as.str.WriteString("(env)") | ||||
| } | ||||
| 
 | ||||
| func (as *AstStringer) visitWhileStmt(w *WhileStmt) { | ||||
| 	as.str.WriteString("(while ") | ||||
| 	w.cond.accept(as) | ||||
| 	as.str.WriteString(" ") | ||||
| 	w.body.accept(as) | ||||
| 	as.str.WriteString(")") | ||||
| } | ||||
|  |  | |||
							
								
								
									
										5
									
								
								env.go
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								env.go
									
										
									
									
									
								
							|  | @ -33,5 +33,10 @@ func (env *Environment) exists(key string) bool { | |||
| } | ||||
| 
 | ||||
| func (env *Environment) set(key string, val any) { | ||||
| 
 | ||||
| 	if env.parent != nil && env.parent.exists(key) { | ||||
| 		env.parent.set(key, val) | ||||
| 	} | ||||
| 
 | ||||
| 	env.values[key] = val | ||||
| } | ||||
|  |  | |||
|  | @ -210,7 +210,12 @@ func (i *Interpreter) visitEnvStmt(e *EnvStmt) { | |||
| 		fmt.Printf("%*s", ident, "") | ||||
| 		fmt.Printf("%+v\n", *e) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (i *Interpreter) visitWhileStmt(w *WhileStmt) { | ||||
| 	for isTruthy(i.evaluate(w.cond)) { | ||||
| 		w.body.accept(i) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (i *Interpreter) panic(re *RuntimeError) { | ||||
|  |  | |||
							
								
								
									
										28
									
								
								parser.go
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								parser.go
									
										
									
									
									
								
							|  | @ -66,14 +66,20 @@ func (p *Parser) varDecl() Stmt { | |||
| 	return &VarStmt{name, initializer} | ||||
| } | ||||
| 
 | ||||
| // statement -> exprStmt | printStmt | block | ifStmt | env | ||||
| // statement ->  exprStmt | ||||
| // | ||||
| //	| whileStmt | ||||
| //	| printStmt | ||||
| //	| blockStmt | ||||
| //	| ifStmt | ||||
| //	| env | ||||
| func (p *Parser) statement() Stmt { | ||||
| 	if p.match(PRINT) { | ||||
| 		return p.printStmt() | ||||
| 	} | ||||
| 
 | ||||
| 	if p.match(LEFT_BRACE) { | ||||
| 		return p.block() | ||||
| 		return p.blockStmt() | ||||
| 	} | ||||
| 
 | ||||
| 	if p.match(IF) { | ||||
|  | @ -84,6 +90,10 @@ func (p *Parser) statement() Stmt { | |||
| 		return p.envStmt() | ||||
| 	} | ||||
| 
 | ||||
| 	if p.match(WHILE) { | ||||
| 		return p.whileStmt() | ||||
| 	} | ||||
| 
 | ||||
| 	return p.exprStmt() | ||||
| } | ||||
| 
 | ||||
|  | @ -111,8 +121,8 @@ func (p *Parser) printStmt() Stmt { | |||
| 	return &PrintStmt{expr} | ||||
| } | ||||
| 
 | ||||
| // block -> "{" statement* "}" | ||||
| func (p *Parser) block() Stmt { | ||||
| // blockStmt -> "{" statement* "}" | ||||
| func (p *Parser) blockStmt() Stmt { | ||||
| 
 | ||||
| 	stmts := []Stmt{} | ||||
| 	for !p.check(RIGHT_BRACE) && !p.isAtEnd() { | ||||
|  | @ -140,6 +150,16 @@ func (p *Parser) ifStmt() Stmt { | |||
| 	return &IfStmt{name, expr, then, or} | ||||
| } | ||||
| 
 | ||||
| // while -> "while" "(" expression ")" statement | ||||
| func (p *Parser) whileStmt() Stmt { | ||||
| 	p.consume(LEFT_PAREN, "Expect '(' after 'while'.") | ||||
| 	cond := p.expression() | ||||
| 	p.consume(RIGHT_PAREN, "Expect ')' after 'while' expression.") | ||||
| 	body := p.statement() | ||||
| 
 | ||||
| 	return &WhileStmt{cond, body} | ||||
| } | ||||
| 
 | ||||
| // env -> "env" ";" | ||||
| func (p *Parser) envStmt() Stmt { | ||||
| 	p.consume(SEMICOLON, "Expect ';' after 'env'.") | ||||
|  |  | |||
							
								
								
									
										13
									
								
								stmt.go
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								stmt.go
									
										
									
									
									
								
							|  | @ -7,6 +7,7 @@ type StmtVisitor interface { | |||
| 	visitPrintStmt(p *PrintStmt) | ||||
| 	visitBlockStmt(b *BlockStmt) | ||||
| 	visitEnvStmt(e *EnvStmt) | ||||
| 	visitWhileStmt(w *WhileStmt) | ||||
| } | ||||
| 
 | ||||
| type Stmt interface { | ||||
|  | @ -40,12 +41,18 @@ type IfStmt struct { | |||
| 	or   Stmt | ||||
| } | ||||
| 
 | ||||
| type WhileStmt struct { | ||||
| 	cond Expr | ||||
| 	body Stmt | ||||
| } | ||||
| 
 | ||||
| func (i *IfStmt) stmt()    {} | ||||
| func (e *EnvStmt) stmt()   {} | ||||
| func (vs *VarStmt) stmt()  {} | ||||
| func (es *ExprStmt) stmt() {} | ||||
| func (p *PrintStmt) stmt() {} | ||||
| func (b *BlockStmt) stmt() {} | ||||
| func (e *EnvStmt) stmt()   {} | ||||
| func (w *WhileStmt) stmt() {} | ||||
| 
 | ||||
| func (p *PrintStmt) accept(v StmtVisitor) { | ||||
| 	v.visitPrintStmt(p) | ||||
|  | @ -70,3 +77,7 @@ func (i *IfStmt) accept(v StmtVisitor) { | |||
| func (e *EnvStmt) accept(v StmtVisitor) { | ||||
| 	v.visitEnvStmt(e) | ||||
| } | ||||
| 
 | ||||
| func (w *WhileStmt) accept(v StmtVisitor) { | ||||
| 	v.visitWhileStmt(w) | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue