about summary refs log tree commit diff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/lang/ast/stmt.go7
-rw-r--r--pkg/lang/parser/stmts.go96
-rw-r--r--pkg/lang/scanner/token/kind.go3
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"