From e0161c493867e788ad9db208247f3275e2d057dc Mon Sep 17 00:00:00 2001 From: Mel Date: Mon, 8 Aug 2022 23:11:23 +0000 Subject: Parse use and global statements --- pkg/lang/ast/stmt.go | 7 ++- pkg/lang/parser/stmts.go | 96 +++++++++++++++++++++++++++++++++++++++++- pkg/lang/scanner/token/kind.go | 3 ++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/pkg/lang/ast/stmt.go b/pkg/lang/ast/stmt.go index 7545bee..5b17851 100644 --- a/pkg/lang/ast/stmt.go +++ b/pkg/lang/ast/stmt.go @@ -7,6 +7,7 @@ type StmtKind int const ( StmtKindEmpty StmtKind = iota StmtKindUse + StmtKindGlobal StmtKindFnDecl StmtKindTypeDecl StmtKindVarDecl @@ -31,10 +32,14 @@ type StmtT[T any] struct { type StmtUse struct { Globals []IdentNode - Modules []IdentNode + Module IdentNode Author IdentNode } +type StmtGlobal struct { + Name IdentNode +} + type StmtFnDecl struct { Name IdentNode Args []IdentNode 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) { diff --git a/pkg/lang/scanner/token/kind.go b/pkg/lang/scanner/token/kind.go index bedbada..a52f232 100644 --- a/pkg/lang/scanner/token/kind.go +++ b/pkg/lang/scanner/token/kind.go @@ -35,6 +35,7 @@ const ( KwUse KwFrom KwBy + KwGlobal // Data Tokens Ident @@ -127,6 +128,8 @@ func (tk TokenKind) String() string { return "from" case KwBy: return "by" + case KwGlobal: + return "global" case Ident: return "ident" -- cgit 1.4.1