aboutsummaryrefslogtreecommitdiff
path: root/pkg/lang/compiler/scope
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/compiler/scope')
-rw-r--r--pkg/lang/compiler/scope/scope_chain.go24
-rw-r--r--pkg/lang/compiler/scope/scopes.go27
2 files changed, 51 insertions, 0 deletions
diff --git a/pkg/lang/compiler/scope/scope_chain.go b/pkg/lang/compiler/scope/scope_chain.go
index 683d53a..4d5bbcf 100644
--- a/pkg/lang/compiler/scope/scope_chain.go
+++ b/pkg/lang/compiler/scope/scope_chain.go
@@ -10,6 +10,7 @@ type ScopeChain struct {
symbolScopes []SymbolScope // All other scopes are bound to this by ID.
functionScopes []FunctionScope
+ loopScopes []LoopScope
}
func NewScopeChain() ScopeChain {
@@ -19,11 +20,14 @@ func NewScopeChain() ScopeChain {
functionScopes := make([]FunctionScope, 1)
functionScopes[0] = NewFunctionScope(0, "") // Root function to house top-scope sub units
+ loopScopes := make([]LoopScope, 0)
+
return ScopeChain{
nameToSymbol: make(map[string]SymbolID),
symbolScopes: symbolScopes,
functionScopes: functionScopes,
+ loopScopes: loopScopes,
}
}
@@ -51,6 +55,14 @@ func (sc *ScopeChain) CurrentFunction() *FunctionScope {
return &sc.functionScopes[len(sc.functionScopes)-1]
}
+func (sc *ScopeChain) CurrentLoop() *LoopScope {
+ if len(sc.loopScopes) == 0 {
+ return nil
+ }
+
+ return &sc.loopScopes[len(sc.loopScopes)-1]
+}
+
func (sc *ScopeChain) Enter() {
sc.symbolScopes = append(sc.symbolScopes, NewSymbolScope())
}
@@ -60,6 +72,18 @@ func (sc *ScopeChain) EnterFunction(unit code.Marker) {
sc.functionScopes = append(sc.functionScopes, NewFunctionScope(sc.CurrentScopeID(), unit))
}
+func (sc *ScopeChain) EnterLoop() (code.Marker, code.Marker) {
+ parentMarker := sc.CreateAnonymousFunctionSubUnit()
+
+ breakMarker := parentMarker.SubMarker("end")
+ continueMarker := parentMarker.SubMarker("start")
+
+ sc.Enter()
+ sc.loopScopes = append(sc.loopScopes, NewLoopScope(sc.CurrentScopeID(), breakMarker, continueMarker))
+
+ return breakMarker, continueMarker
+}
+
func (sc *ScopeChain) Exit() {
if sc.CurrentScopeID() == 0 {
return
diff --git a/pkg/lang/compiler/scope/scopes.go b/pkg/lang/compiler/scope/scopes.go
index 39e48ef..5cfcd5d 100644
--- a/pkg/lang/compiler/scope/scopes.go
+++ b/pkg/lang/compiler/scope/scopes.go
@@ -9,6 +9,7 @@ type ScopeKind int
const (
ScopeKindNormal ScopeKind = iota
ScopeKindFunction
+ ScopeKindLoop
)
type SymbolScope struct {
@@ -48,3 +49,29 @@ func (sf FunctionScope) Unit() code.Marker {
func (sf FunctionScope) IsRootScope() bool {
return sf.ID() == ScopeID(0)
}
+
+type LoopScope struct {
+ id ScopeID
+ breakMarker code.Marker
+ continueMarker code.Marker
+}
+
+func NewLoopScope(id ScopeID, breakMarker code.Marker, continueMarker code.Marker) LoopScope {
+ return LoopScope{
+ id: id,
+ breakMarker: breakMarker,
+ continueMarker: continueMarker,
+ }
+}
+
+func (sl LoopScope) ID() ScopeID {
+ return sl.id
+}
+
+func (sl LoopScope) BreakMarker() code.Marker {
+ return sl.breakMarker
+}
+
+func (sl LoopScope) ContinueMarker() code.Marker {
+ return sl.continueMarker
+}