<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/subex/subexast.go
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2024-03-29 09:49:26 +0000
committerCharlie Stanton <charlie@shtanton.xyz>2024-03-29 09:49:26 +0000
commit080a24e894f125d4f1741cfdcba7cb722304d209 (patch)
tree78c12af110a8a239b6a3b1f828e4f193fcb8cd32 /subex/subexast.go
parent510a8c95ce112617c33f8dfb865e752db0716cb1 (diff)
downloadstred-go-080a24e894f125d4f1741cfdcba7cb722304d209.tar
Completely remove the path space
The new design uses deeply nested values in the value space instead.
Diffstat (limited to 'subex/subexast.go')
-rw-r--r--subex/subexast.go287
1 files changed, 160 insertions, 127 deletions
diff --git a/subex/subexast.go b/subex/subexast.go
index e02091d..cc7313b 100644
--- a/subex/subexast.go
+++ b/subex/subexast.go
@@ -7,43 +7,42 @@ import (
// A node in the AST of a subex
type SubexAST interface {
- compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState
+ compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState
}
// Process the first subex, then the second, splitting the input text in two
type SubexASTConcat struct {
First, Second SubexAST
}
-func (ast SubexASTConcat) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- return ast.First.compileWith(ast.Second.compileWith(next, slotMap, runic), slotMap, runic)
+func (ast SubexASTConcat) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ return ast.First.compileWith(
+ ast.Second.compileWith(next, slotMap, inType, outType),
+ slotMap,
+ inType,
+ outType,
+ )
}
func (ast SubexASTConcat) String() string {
return fmt.Sprintf("(%v)(%v)", ast.First, ast.Second)
}
// Processing a subex and storing the output in a slot instead of outputting it
-type SubexASTStore struct {
+type SubexASTStoreValues struct {
Match SubexAST
Slot rune
}
-func (ast SubexASTStore) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTStoreValues) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
id := slotMap.getId(ast.Slot)
newNext := ast.Match.compileWith(&SubexStoreEndState {
slot: id,
next: next,
- }, slotMap, runic)
+ }, slotMap, inType, ValueType)
- if !runic {
- return &SubexCaptureBeginState {
- next: newNext,
- }
- } else {
- return &SubexCaptureRunesBeginState {
- next: newNext,
- }
+ return &SubexCaptureBeginState {
+ next: newNext,
}
}
-func (ast SubexASTStore) String() string {
+func (ast SubexASTStoreValues) String() string {
return fmt.Sprintf("$%c(%v)", ast.Slot, ast.Match)
}
@@ -51,10 +50,10 @@ func (ast SubexASTStore) String() string {
type SubexASTOr struct {
First, Second SubexAST
}
-func (ast SubexASTOr) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTOr) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
return &SubexGroupState {
- ast.First.compileWith(next, slotMap, runic),
- ast.Second.compileWith(next, slotMap, runic),
+ ast.First.compileWith(next, slotMap, inType, outType),
+ ast.Second.compileWith(next, slotMap, inType, outType),
}
}
func (ast SubexASTOr) String() string {
@@ -84,19 +83,24 @@ func (cr ConvexRange) decrement() ConvexRange {
return ConvexRange{cr.Start - 1, cr.End - 1}
}
}
-func (cr ConvexRange) compile(content SubexAST, next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (cr ConvexRange) compile(content SubexAST, next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
min, _ := cr.minmax()
if min != 0 {
- return content.compileWith(cr.decrement().compile(content, next, slotMap, runic), slotMap, runic)
+ return content.compileWith(
+ cr.decrement().compile(content, next, slotMap, inType, outType),
+ slotMap,
+ inType,
+ outType,
+ )
}
if cr.Start == -1 {
state := &SubexGroupState {nil, next}
- state.first = content.compileWith(state, slotMap, runic)
+ state.first = content.compileWith(state, slotMap, inType, outType)
return state
}
if cr.End == -1 {
state := &SubexGroupState {next, nil}
- state.second = content.compileWith(state, slotMap, runic)
+ state.second = content.compileWith(state, slotMap, inType, outType)
return state
}
@@ -104,7 +108,7 @@ func (cr ConvexRange) compile(content SubexAST, next SubexState, slotMap *SlotMa
state := next;
for i := 0; i < cr.Start; i += 1 {
state = &SubexGroupState {
- content.compileWith(state, slotMap, runic),
+ content.compileWith(state, slotMap, inType, outType),
next,
}
}
@@ -114,7 +118,7 @@ func (cr ConvexRange) compile(content SubexAST, next SubexState, slotMap *SlotMa
for i := 0; i < cr.End; i += 1 {
state = &SubexGroupState {
next,
- content.compileWith(state, slotMap, runic),
+ content.compileWith(state, slotMap, inType, outType),
}
}
return state
@@ -127,10 +131,13 @@ type SubexASTRepeat struct {
Content SubexAST
Acceptable []ConvexRange
}
-func (ast SubexASTRepeat) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTRepeat) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != outType {
+ panic("Invalid types")
+ }
var state SubexState = &SubexDeadState{}
for _, convex := range ast.Acceptable {
- state = &SubexGroupState {state, convex.compile(ast.Content, next, slotMap, runic)}
+ state = &SubexGroupState {state, convex.compile(ast.Content, next, slotMap, inType, outType)}
}
return state
}
@@ -142,7 +149,10 @@ func (ast SubexASTRepeat) String() string {
type SubexASTCopyScalar struct {
Scalar walk.Scalar
}
-func (ast SubexASTCopyScalar) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyScalar) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCopyState{
filter: selectScalarFilter {ast.Scalar},
next: next,
@@ -153,17 +163,26 @@ func (ast SubexASTCopyScalar) String() string {
}
type SubexASTCopyAnyRune struct {}
-func (ast SubexASTCopyAnyRune) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyAnyRune) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != RuneType || outType != RuneType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCopyRuneState {
next: next,
filter: anyRuneFilter{},
}
}
+func (ast SubexASTCopyAnyRune) String() string {
+ return "."
+}
type SubexASTCopyRune struct {
rune rune
}
-func (ast SubexASTCopyRune) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyRune) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != RuneType || outType != RuneType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCopyRuneState {
next: next,
filter: selectRuneFilter {ast.rune},
@@ -172,7 +191,10 @@ func (ast SubexASTCopyRune) compileWith(next SubexState, slotMap *SlotMap, runic
// Read in a single atom that must be a boolean and output it unchanged
type SubexASTCopyBool struct {}
-func (ast SubexASTCopyBool) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyBool) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCopyState {
next: next,
filter: anyBoolFilter{},
@@ -184,7 +206,10 @@ func (ast SubexASTCopyBool) String() string {
// Read in a single atom that must be a number and output it unchanged
type SubexASTCopyNumber struct {}
-func (ast SubexASTCopyNumber) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyNumber) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCopyState {
next: next,
filter: anyNumberFilter{},
@@ -194,34 +219,12 @@ func (ast SubexASTCopyNumber) String() string {
return "%"
}
-// Read in a full string value and copy it out unchanged
-// # is equivalent to "_{-0}"
-// TODO
-// type SubexASTCopyString struct {}
-// func (ast SubexASTCopyString) compileWith(next SubexState, slotMap *SlotMap) SubexState {
-// stringAtomState := &SubexCopyStringAtomState {
-// next: nil,
-// }
-// stringContentState := &SubexGroupState {
-// &SubexCopyScalarState {
-// scalar: walk.NewAtomStringTerminal(),
-// next: next,
-// },
-// stringAtomState,
-// }
-// stringAtomState.next = stringContentState
-// return &SubexCopyScalarState {
-// scalar: walk.NewAtomStringTerminal(),
-// next: stringContentState,
-// }
-// }
-// func (ast SubexASTCopyString) String() string {
-// return "#"
-// }
-
// Read in any single Atom and output it unchanged
type SubexASTCopyAnyValue struct {}
-func (ast SubexASTCopyAnyValue) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTCopyAnyValue) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCopyState {
next: next,
filter: anyValueFilter{},
@@ -231,6 +234,7 @@ func (ast SubexASTCopyAnyValue) String() string {
return "."
}
+/*
type OutputContentAST interface {
compile(slotMap *SlotMap) OutputContent
}
@@ -273,25 +277,66 @@ func (ast SubexASTOutput) compileWith(next SubexState, slotMap *SlotMap, runic b
func (ast SubexASTOutput) String() string {
return "=...="
}
+*/
-// Read in a repeated subex separated by a delimiter. Greedy
-type SubexASTJoin struct {
- Content, Delimiter SubexAST
+type OutputValueAST interface {
+ compile(slotMap *SlotMap) OutputValue
+}
+
+type OutputValueLoadAST struct {
+ slot rune
}
-func (ast SubexASTJoin) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- afterContentState := &SubexGroupState {
- nil,
- next,
+func (ast OutputValueLoadAST) compile(slotMap *SlotMap) OutputValue {
+ return OutputValueLoad {
+ slotMap.getId(ast.slot),
}
- manyContentsState := ast.Content.compileWith(afterContentState, slotMap, runic)
- afterContentState.first = ast.Delimiter.compileWith(manyContentsState, slotMap, runic)
- return &SubexGroupState {
- manyContentsState,
- next,
+}
+
+type OutputValueLiteralAST struct {
+ scalar walk.Scalar
+}
+func (ast OutputValueLiteralAST) compile(slotMap *SlotMap) OutputValue {
+ return OutputValueLiteral {
+ ast.scalar,
+ }
+}
+
+type SubexASTOutputValues struct {
+ Replacement []OutputValueAST
+}
+func (ast SubexASTOutputValues) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if outType != ValueType {
+ panic("Invalid outType")
+ }
+ var content []OutputValue
+ for _, el := range ast.Replacement {
+ content = append(content, el.compile(slotMap))
+ }
+ return &SubexOutputValuesState {
+ content: content,
+ next: next,
}
}
-func (ast SubexASTJoin) String() string {
- return fmt.Sprintf("(%v);(%v)", ast.Content, ast.Delimiter)
+
+type OutputRuneAST interface {
+ compile(slotMap *SlotMap) OutputRune
+}
+
+type OutputRuneLoadAST struct {
+ slot rune
+}
+func (ast OutputRuneLoadAST) compile(slotMap *SlotMap) OutputRune {
+ return OutputRuneLoad {slotMap.getRuneId(ast.slot)}
+}
+
+type OutputRuneLiteralAST struct {
+ r rune
+}
+func (ast OutputRuneLiteralAST) compile (slotMap *SlotMap) OutputRune {
+ return OutputRuneLiteral {ast.r}
+}
+
+type SubexASTOutputRunes struct {
}
// Run each input Atom through a map to produce an output Atom
@@ -314,12 +359,15 @@ func (ast SubexASTJoin) String() string {
type SubexASTSum struct {
Content SubexAST
}
-func (ast SubexASTSum) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTSum) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCaptureBeginState {
next: ast.Content.compileWith(&SubexArithmeticEndState {
next: next,
calculate: sumValues,
- }, slotMap, runic),
+ }, slotMap, inType, outType),
}
}
func (ast SubexASTSum) String() string {
@@ -330,12 +378,15 @@ func (ast SubexASTSum) String() string {
type SubexASTProduct struct {
Content SubexAST
}
-func (ast SubexASTProduct) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTProduct) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCaptureBeginState {
next: ast.Content.compileWith(&SubexArithmeticEndState {
next: next,
calculate: multiplyValues,
- }, slotMap, runic),
+ }, slotMap, inType, outType),
}
}
func (ast SubexASTProduct) String() string {
@@ -347,12 +398,15 @@ func (ast SubexASTProduct) String() string {
type SubexASTNegate struct {
Content SubexAST
}
-func (ast SubexASTNegate) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTNegate) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCaptureBeginState {
next: ast.Content.compileWith(&SubexArithmeticEndState {
next: next,
calculate: negateValues,
- }, slotMap, runic),
+ }, slotMap, inType, outType),
}
}
func (ast SubexASTNegate) String() string {
@@ -360,58 +414,29 @@ func (ast SubexASTNegate) String() string {
}
// Runs the content Subex and collects the output
-// If it is a list of atoms castable to numbers, it takes the reciprocal of them all and outputs them
-// Else it rejects
-type SubexASTReciprocal struct {
- Content SubexAST
-}
-func (ast SubexASTReciprocal) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- return &SubexCaptureBeginState {
- next: ast.Content.compileWith(&SubexArithmeticEndState {
- next: next,
- calculate: reciprocalValues,
- }, slotMap, runic),
- }
-}
-func (ast SubexASTReciprocal) String() string {
- return fmt.Sprintf("(%v)/", ast.Content)
-}
-
-// Runs the content Subex and collects the output
// Maps over the values in the output, casting each to a boolean, notting each and then outputs them
// Rejects if it cannot cast to boolean
type SubexASTNot struct {
Content SubexAST
}
-func (ast SubexASTNot) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTNot) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTNot")
+ }
return &SubexCaptureBeginState {
next: ast.Content.compileWith(&SubexArithmeticEndState {
next: next,
calculate: notValues,
- }, slotMap, runic),
+ }, slotMap, ValueType, ValueType),
}
}
func (ast SubexASTNot) String() string {
return fmt.Sprintf("(%v)!", ast.Content)
}
-// Runs the content Subex and collects the output
-// Replaces it with true if all output values are equal and false otherwise
-type SubexASTEqual struct {
- Content SubexAST
-}
-func (ast SubexASTEqual) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- return &SubexCaptureBeginState {
- next: ast.Content.compileWith(&SubexArithmeticEndState {
- next: next,
- calculate: equalValues,
- }, slotMap, runic),
- }
-}
-
// Does nothing
type SubexASTEmpty struct {}
-func (ast SubexASTEmpty) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTEmpty) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
return next
}
func (ast SubexASTEmpty) String() string {
@@ -422,9 +447,9 @@ func (ast SubexASTEmpty) String() string {
type SubexASTDiscard struct {
Content SubexAST
}
-func (ast SubexASTDiscard) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
- newNext := ast.Content.compileWith(&SubexDiscardState {next}, slotMap, runic)
- if !runic {
+func (ast SubexASTDiscard) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ newNext := ast.Content.compileWith(&SubexDiscardState {next}, slotMap, inType, outType)
+ if inType == ValueType {
return &SubexCaptureBeginState {
next: newNext,
}
@@ -442,7 +467,10 @@ func (ast SubexASTDiscard) String() string {
type SubexASTEnterArray struct {
Content SubexAST
}
-func (ast SubexASTEnterArray) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTEnterArray) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTEnterArray")
+ }
return &SubexCaptureBeginState {
next: &SubexIncrementNestState {
next: &SubexCopyState {
@@ -451,13 +479,14 @@ func (ast SubexASTEnterArray) compileWith(next SubexState, slotMap *SlotMap, run
next: &SubexCaptureBeginState {
next: ast.Content.compileWith(
&SubexDiscardTerminalState {
- terminal: walk.ArrayEndTerminal{},
+ terminal: walk.ArrayEnd,
next: &SubexDecrementNestState {
next: &SubexConstructArrayState {next: next},
},
},
slotMap,
- runic,
+ ValueType,
+ ValueType,
),
},
},
@@ -469,22 +498,26 @@ func (ast SubexASTEnterArray) compileWith(next SubexState, slotMap *SlotMap, run
type SubexASTEnterString struct {
Content SubexAST
}
-func (ast SubexASTEnterString) compileWith(next SubexState, slotMap *SlotMap, runic bool) SubexState {
+func (ast SubexASTEnterString) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState {
+ if inType != ValueType || outType != ValueType {
+ panic("Invalid types for SubexASTEnterString")
+ }
return &SubexCaptureBeginState {
- next: &SubexIncrementNestState {
- next: &SubexCopyState {
- filter: anyStringFilter{},
- next: &SubexDiscardState {
+ next: &SubexCopyState {
+ filter: anyStringFilter{},
+ next: &SubexDiscardState {
+ next: &SubexIncrementNestState {
next: &SubexCaptureRunesBeginState {
next: ast.Content.compileWith(
- &SubexDecrementNestState {
- next: &SubexDiscardTerminalState {
- terminal: walk.StringEndTerminal{},
+ &SubexDiscardTerminalState {
+ terminal: walk.StringEnd,
+ next: &SubexDecrementNestState {
next: &SubexConstructStringState {next: next},
},
},
slotMap,
- true,
+ RuneType,
+ RuneType,
),
},
},