while loops

This commit is contained in:
uan
2026-02-07 15:48:59 +01:00
parent 58f0dfa969
commit 9d26256023
5 changed files with 47 additions and 7 deletions

View File

@@ -211,7 +211,8 @@ User {
### Control Flow ### Control Flow
Control flow in One is still quite limited, as the `for` keyword has not been implemented yet. `if`, `else` and `elif` statements are fully implemented and are written like this. Control flow in One isn't fully implemented yet, but it is already functional.
`if`, `else` and `elif` statements are fully implemented and are written like this:
``` ```
let x int = 17; let x int = 17;
@@ -225,7 +226,15 @@ if x >= 100 {
} }
``` ```
Using parentheses around the condition isn't necessary. `while` loops are very similar, and can be written like this:
```
let i int = 0;
while i < 10 {
print(i);
i++;
}
```
### The main function ### The main function

View File

@@ -1,3 +1,4 @@
module main module main
import strings import strings
@@ -158,6 +159,12 @@ fn (mut g Generator) gen_stmt(stmt Stmt) {
g.out.write_string(') ') g.out.write_string(') ')
g.gen_stmt(stmt.block) g.gen_stmt(stmt.block)
} }
WhileLoop {
g.out.write_string('while (')
g.gen_expr(stmt.guard)
g.out.write_string(') ')
g.gen_stmt(stmt.block)
}
} }
} }

View File

@@ -10,7 +10,7 @@ enum TokenType as u8 {
kw_if kw_if
kw_else kw_else
kw_elif kw_elif
kw_for kw_while
kw_break kw_break
kw_fn kw_fn
kw_return kw_return
@@ -106,7 +106,7 @@ fn toktype_from_kw(kw string) TokenType {
'if' {.kw_if} 'if' {.kw_if}
'else' {.kw_else} 'else' {.kw_else}
'elif' {.kw_elif} 'elif' {.kw_elif}
'for' {.kw_for} 'while' {.kw_while}
'break' {.kw_break} 'break' {.kw_break}
'fn' {.kw_fn} 'fn' {.kw_fn}
'return' {.kw_return} 'return' {.kw_return}
@@ -133,7 +133,7 @@ fn is_real(str string) bool {
fn is_keyword(str string) bool { fn is_keyword(str string) bool {
return [ return [
"void", "int", "real", "bool", "string", "if", "else", "elif", "for", "break", "fn", "return", "let", "const", "true", "false", "print", "class", "immutable" "void", "int", "real", "bool", "string", "if", "else", "elif", "while", "break", "fn", "return", "let", "const", "true", "false", "print", "class", "immutable"
].contains(str) ].contains(str)
} }

BIN
one

Binary file not shown.

View File

@@ -122,7 +122,9 @@ fn (mut s SymbolTable) is_in_global_scope() bool {
// ------------------------------------------- Expressions // ------------------------------------------- Expressions
type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | StringLiteral | Variable | TypeExpr | Function | TypeCast | ParenExpr | PrintExpr | FnCall | ClassMember | ClassInstantiation | MemberAccess type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | StringLiteral |
Variable | TypeExpr | Function | TypeCast | ParenExpr | PrintExpr | FnCall | ClassMember |
ClassInstantiation | MemberAccess
struct VoidExpr {} struct VoidExpr {}
@@ -204,7 +206,8 @@ struct FnCall {
// ------------------------------------------- Statements // ------------------------------------------- Statements
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | IfStmt | ElseStmt | ElifStmt | FuncDecl | Param | ClassDecl type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | IfStmt | ElseStmt | ElifStmt | FuncDecl | Param |
ClassDecl | WhileLoop
struct VarDecl { struct VarDecl {
name string name string
@@ -251,6 +254,11 @@ struct ElifStmt {
block Block block Block
} }
struct WhileLoop {
guard Expr
block Block
}
struct Param { struct Param {
name string name string
type string type string
@@ -529,6 +537,10 @@ fn (mut p Parser) get_expr_is_immutable(expr Expr) bool {
memberinfo := classinfo.members_info[expr.member] or {parse_error("Undefined member ${expr.member}")} memberinfo := classinfo.members_info[expr.member] or {parse_error("Undefined member ${expr.member}")}
memberinfo.is_immutable memberinfo.is_immutable
} }
Variable {
varinfo := p.symbols.lookup_var(expr.name) or {parse_error("Undefined variable ${expr.name}")}
varinfo.is_immutable
}
else {true} else {true}
} }
} }
@@ -616,6 +628,7 @@ fn (mut p Parser) parse_statement() Stmt {
.kw_if {return p.parse_if()} .kw_if {return p.parse_if()}
.kw_else {return p.parse_else()} .kw_else {return p.parse_else()}
.kw_elif {return p.parse_elif()} .kw_elif {return p.parse_elif()}
.kw_while {return p.parse_while()}
else {return p.parse_expr_stmt()} else {return p.parse_expr_stmt()}
} }
} }
@@ -768,6 +781,17 @@ fn (mut p Parser) parse_return_stmt() ReturnStmt {
} }
} }
fn (mut p Parser) parse_while() WhileLoop {
p.expect(.kw_while)
cond := p.parse_expr(.base)
if p.get_expr_type(cond) != 'bool' {
parse_error('While loop guard must be of type bool')
}
block := p.parse_block(false)
return WhileLoop {cond, block}
}
fn (mut p Parser) parse_if() IfStmt { fn (mut p Parser) parse_if() IfStmt {
p.expect(.kw_if) p.expect(.kw_if)
cond := p.parse_expr(.base) cond := p.parse_expr(.base)