diff options
Diffstat (limited to 'pkg/lang/parser/stmts.go')
| -rw-r--r-- | pkg/lang/parser/stmts.go | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/pkg/lang/parser/stmts.go b/pkg/lang/parser/stmts.go index 33719ce..c20f7a0 100644 --- a/pkg/lang/parser/stmts.go +++ b/pkg/lang/parser/stmts.go @@ -10,6 +10,8 @@ func (p *Parser) parseStmt() (ast.Stmt, error) { switch p.peek().Kind { case token.KwUse: return p.parseUseStmt() + case token.KwGlobal: + return p.parseGlobalStmt() case token.KwFn: return p.parseFnDeclStmt() case token.KwType: @@ -40,7 +42,99 @@ func (p *Parser) parseStmt() (ast.Stmt, error) { } func (p *Parser) parseUseStmt() (ast.Stmt, error) { - panic("not implemented") + // UseStmt = (UseModule | UseGlobals) ModuleAuthor? + // UseModule = "use" IDENT + // UseGlobals = "use" IDENT ("," IDENT)* "from" IDENT + // ModuleAuthor = "by" IDENT + + useTok, err := p.expect(token.KwUse) + if err != nil { + return ast.Stmt{}, err + } + + firstName, err := p.parseIdent() + if err != nil { + return ast.Stmt{}, err + } + + useStmt := ast.StmtUse{} + if p.peek().Kind == token.Comma || p.peek().Kind == token.KwFrom { + // UseGlobals + usedGlobals := []ast.IdentNode{firstName} + for p.peek().Kind != token.KwFrom { + if _, err := p.expect(token.Comma); err != nil { + return ast.Stmt{}, err + } + + name, err := p.parseIdent() + if err != nil { + return ast.Stmt{}, err + } + + usedGlobals = append(usedGlobals, name) + } + + if _, err := p.expect(token.KwFrom); err != nil { + return ast.Stmt{}, err + } + + fromName, err := p.parseIdent() + if err != nil { + return ast.Stmt{}, err + } + + useStmt = ast.StmtUse{ + Globals: usedGlobals, + Module: fromName, + } + } else { + // UseModule + useStmt = ast.StmtUse{ + Module: firstName, + } + } + + if p.peek().Kind == token.KwBy { + // ModuleAuthor + if _, err := p.expect(token.KwBy); err != nil { + return ast.Stmt{}, err + } + + author, err := p.parseIdent() + if err != nil { + return ast.Stmt{}, err + } + + useStmt.Author = author + } + + return ast.Stmt{ + At: useTok.At, + Kind: ast.StmtKindUse, + Value: useStmt, + }, nil +} + +func (p *Parser) parseGlobalStmt() (ast.Stmt, error) { + // GlobalStmt = "global" IDENT + + globalTok, err := p.expect(token.KwGlobal) + if err != nil { + return ast.Stmt{}, err + } + + name, err := p.parseIdent() + if err != nil { + return ast.Stmt{}, err + } + + return ast.Stmt{ + At: globalTok.At, + Kind: ast.StmtKindGlobal, + Value: ast.StmtGlobal{ + Name: name, + }, + }, nil } func (p *Parser) parseFnDeclStmt() (ast.Stmt, error) { |
