about summary refs log tree commit diff
path: root/pkg/lang/parser/stmts.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/parser/stmts.go')
-rw-r--r--pkg/lang/parser/stmts.go96
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) {