about summary refs log tree commit diff
path: root/pkg/lang/compiler/scope
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-08-11 01:25:47 +0000
committerMel <einebeere@gmail.com>2022-08-11 01:25:47 +0000
commit86f31acf6789be116dcc54ed85b069a37c0f7aa8 (patch)
treebc7afd6a8c340825996d29c6cfd392ae42b4fbd5 /pkg/lang/compiler/scope
parentc46b2bc7ce6df1f2c6c9494ef08015ec29992da5 (diff)
downloadjinx-86f31acf6789be116dcc54ed85b069a37c0f7aa8.tar.zst
jinx-86f31acf6789be116dcc54ed85b069a37c0f7aa8.zip
Actual modules and core
Diffstat (limited to 'pkg/lang/compiler/scope')
-rw-r--r--pkg/lang/compiler/scope/scope_chain.go37
-rw-r--r--pkg/lang/compiler/scope/scopes.go2
-rw-r--r--pkg/lang/compiler/scope/symbol.go14
3 files changed, 52 insertions, 1 deletions
diff --git a/pkg/lang/compiler/scope/scope_chain.go b/pkg/lang/compiler/scope/scope_chain.go
index f386017..0c8f5cf 100644
--- a/pkg/lang/compiler/scope/scope_chain.go
+++ b/pkg/lang/compiler/scope/scope_chain.go
@@ -160,6 +160,35 @@ func (sc *ScopeChain) DeclareTemporary() int {
 	return len(sc.Current().variableSymbols) // :)
 }
 
+func (sc *ScopeChain) DeclareGlobal(name, module, author string) bool {
+	if _, ok := sc.nameToSymbol[name]; ok {
+		return false
+	}
+
+	current := sc.Current()
+	indexInScope := len(current.globalSymbols)
+
+	symbolID := SymbolID{
+		symbolKind:   SymbolKindGlobal,
+		scopeID:      sc.CurrentScopeID(),
+		indexInScope: indexInScope,
+	}
+
+	globalID := fmt.Sprintf("%s:%s:%s", author, module, name)
+
+	// Declare the symbol in the current scope.
+	current.globalSymbols = append(current.globalSymbols, Symbol[SymbolGlobal]{
+		name: name,
+		data: SymbolGlobal{
+			id: globalID,
+		},
+	})
+
+	sc.nameToSymbol[name] = symbolID
+
+	return true
+}
+
 func (sc *ScopeChain) CreateAnonymousFunctionSubUnit() code.Marker {
 	fnScope := sc.CurrentFunction()
 
@@ -242,3 +271,11 @@ func (sc *ScopeChain) GetEnv(id SymbolID) Symbol[SymbolEnv] {
 		},
 	}
 }
+
+func (sc *ScopeChain) GetGlobal(id SymbolID) Symbol[SymbolGlobal] {
+	if id.symbolKind != SymbolKindGlobal {
+		panic("incorrect symbol id kind given")
+	}
+
+	return sc.symbolScopes[id.scopeID].globalSymbols[id.indexInScope]
+}
diff --git a/pkg/lang/compiler/scope/scopes.go b/pkg/lang/compiler/scope/scopes.go
index 2a9453a..e1a7a9f 100644
--- a/pkg/lang/compiler/scope/scopes.go
+++ b/pkg/lang/compiler/scope/scopes.go
@@ -14,11 +14,13 @@ const (
 
 type SymbolScope struct {
 	variableSymbols []Symbol[SymbolVariable]
+	globalSymbols []Symbol[SymbolGlobal]
 }
 
 func NewSymbolScope() SymbolScope {
 	return SymbolScope{
 		variableSymbols: make([]Symbol[SymbolVariable], 0),
+		globalSymbols:   make([]Symbol[SymbolGlobal], 0),
 	}
 }
 
diff --git a/pkg/lang/compiler/scope/symbol.go b/pkg/lang/compiler/scope/symbol.go
index b87d5aa..8bfe60a 100644
--- a/pkg/lang/compiler/scope/symbol.go
+++ b/pkg/lang/compiler/scope/symbol.go
@@ -26,6 +26,8 @@ const (
 	// An env symbol is bound to a local on the stack, outside of the function's scope.
 	// Emitted at lookup time, so the SymbolScope has no array for them.
 	SymbolKindEnv SymbolKind = iota
+	// A global symbol is bound to a global from a dependency.
+	SymbolKindGlobal SymbolKind = iota
 )
 
 func (s SymbolKind) String() string {
@@ -34,6 +36,8 @@ func (s SymbolKind) String() string {
 		return "variable"
 	case SymbolKindEnv:
 		return "env"
+	case SymbolKindGlobal:
+		return "global"
 	default:
 		panic("unknown symbol kind")
 	}
@@ -49,7 +53,7 @@ func (s Symbol[D]) Data() D {
 }
 
 type SymbolData interface {
-	SymbolVariable | SymbolEnv
+	SymbolVariable | SymbolEnv | SymbolGlobal
 }
 
 type SymbolVariable struct {
@@ -67,3 +71,11 @@ type SymbolEnv struct {
 func (se SymbolEnv) IndexInEnv() int {
 	return se.indexInEnv
 }
+
+type SymbolGlobal struct {
+	id string
+}
+
+func (sg SymbolGlobal) ID() string {
+	return sg.id
+}
\ No newline at end of file