aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-08-08 23:11:23 +0000
committerMel <einebeere@gmail.com>2022-08-08 23:45:16 +0000
commite0161c493867e788ad9db208247f3275e2d057dc (patch)
tree078807561155927ee40b0fc0fde011b49e859b87
parent5a6d4664e4417763b4a7d9f215e42102fa1b3fd4 (diff)
downloadjinx-e0161c493867e788ad9db208247f3275e2d057dc.tar.zst
jinx-e0161c493867e788ad9db208247f3275e2d057dc.zip
Parse use and global statements
-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"