From 658900fcae610caace83a112ac0ee865108ebc92 Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Sun, 7 Apr 2024 15:27:36 +0100 Subject: Change output subex internals to allow structures Also add substitute register syntactic sugar --- subex/subexast.go | 117 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 52 deletions(-) (limited to 'subex/subexast.go') diff --git a/subex/subexast.go b/subex/subexast.go index 2685925..d08ddac 100644 --- a/subex/subexast.go +++ b/subex/subexast.go @@ -46,6 +46,25 @@ func (ast SubexASTStoreValues) String() string { return fmt.Sprintf("$%c(%v)", ast.Slot, ast.Match) } +type SubexASTStoreRunes struct { + Match SubexAST + Slot rune +} +func (ast SubexASTStoreRunes) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { + id := slotMap.getRuneId(ast.Slot) + newNext := ast.Match.compileWith(&SubexStoreRunesEndState { + slot: id, + next: next, + }, slotMap, inType, RuneType) + + return &SubexCaptureRunesBeginState { + next: newNext, + } +} +func (ast SubexASTStoreRunes) String() string { + return fmt.Sprintf("(%v)$%c", ast.Match, ast.Slot) +} + // Try to run the first subex, if it fails then backtrack and use the second type SubexASTOr struct { First, Second SubexAST @@ -148,7 +167,7 @@ type SubexASTCopyScalar struct { } func (ast SubexASTCopyScalar) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { if inType != ValueType || outType != ValueType { - panic("Invalid types for SubexASTNot") + panic("Invalid types for SubexASTCopyScalar") } return &SubexCopyState{ filter: selectScalarFilter {ast.Scalar}, @@ -162,7 +181,7 @@ func (ast SubexASTCopyScalar) String() string { type SubexASTCopyAnyRune struct {} func (ast SubexASTCopyAnyRune) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { if inType != RuneType || outType != RuneType { - panic("Invalid types for SubexASTNot") + panic("Invalid types for SubexASTCopyAnyRune") } return &SubexCopyRuneState { next: next, @@ -170,7 +189,7 @@ func (ast SubexASTCopyAnyRune) compileWith(next SubexState, slotMap *SlotMap, in } } func (ast SubexASTCopyAnyRune) String() string { - return "." + return ".RUNE" } type SubexASTCopyRune struct { @@ -178,19 +197,22 @@ type SubexASTCopyRune struct { } func (ast SubexASTCopyRune) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { if inType != RuneType || outType != RuneType { - panic("Invalid types for SubexASTNot") + panic("Invalid types for SubexASTCopyRune") } return &SubexCopyRuneState { next: next, filter: selectRuneFilter {ast.rune}, } } +func (ast SubexASTCopyRune) String() string { + return string(ast.rune) +} // 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, inType Type, outType Type) SubexState { if inType != ValueType || outType != ValueType { - panic("Invalid types for SubexASTNot") + panic("Invalid types for SubexASTCopyBool") } return &SubexCopyState { next: next, @@ -205,7 +227,7 @@ func (ast SubexASTCopyBool) String() string { type SubexASTCopyNumber struct {} func (ast SubexASTCopyNumber) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { if inType != ValueType || outType != ValueType { - panic("Invalid types for SubexASTNot") + panic("Invalid types for SubexASTCopyNumber") } return &SubexCopyState { next: next, @@ -220,7 +242,6 @@ func (ast SubexASTCopyNumber) String() string { type SubexASTCopyAnyValue struct {} func (ast SubexASTCopyAnyValue) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { if inType != ValueType || outType != ValueType { - fmt.Printf("%v, %v", inType, outType) panic("Invalid types for SubexASTCopyAnyValue") } return &SubexCopyState { @@ -277,64 +298,56 @@ func (ast SubexASTOutput) String() string { } */ -type OutputValueAST interface { - compile(slotMap *SlotMap) OutputValue +type SubexASTOutputValueLiteral struct { + literal walk.Scalar } - -type OutputValueLoadAST struct { - slot rune -} -func (ast OutputValueLoadAST) compile(slotMap *SlotMap) OutputValue { - return OutputValueLoad { - slotMap.getId(ast.slot), +func (ast SubexASTOutputValueLiteral) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { + if outType != ValueType { + panic("Invalid outType for SubexASTOutputValueLiteral") } -} - -type OutputValueLiteralAST struct { - scalar walk.Scalar -} -func (ast OutputValueLiteralAST) compile(slotMap *SlotMap) OutputValue { - return OutputValueLiteral { - ast.scalar, + return &SubexOutputValueLiteralState { + literal: ast.literal, + next: next, } } -type SubexASTOutputValues struct { - Replacement []OutputValueAST +type SubexASTOutputValueLoad struct { + slot rune } -func (ast SubexASTOutputValues) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { +func (ast SubexASTOutputValueLoad) 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)) + panic("Invalid outType for SubexASTOutputValueLoad") } - return &SubexOutputValuesState { - content: content, + return &SubexOutputValueLoadState { + slot: slotMap.getId(ast.slot), next: next, } } -type OutputRuneAST interface { - compile(slotMap *SlotMap) OutputRune -} - -type OutputRuneLoadAST struct { - slot rune +type SubexASTOutputRuneLiteral struct { + literal rune } -func (ast OutputRuneLoadAST) compile(slotMap *SlotMap) OutputRune { - return OutputRuneLoad {slotMap.getRuneId(ast.slot)} +func (ast SubexASTOutputRuneLiteral) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { + if outType != RuneType { + panic("Invalid outType for SubexASTOutputRuneLiteral") + } + return &SubexOutputRuneLiteralState { + literal: ast.literal, + next: next, + } } -type OutputRuneLiteralAST struct { - r rune -} -func (ast OutputRuneLiteralAST) compile (slotMap *SlotMap) OutputRune { - return OutputRuneLiteral {ast.r} +type SubexASTOutputRuneLoad struct { + slot rune } - -type SubexASTOutputRunes struct { +func (ast SubexASTOutputRuneLoad) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { + if outType != RuneType { + panic("Invalid outType for SubexASTOutputRuneLoad") + } + return &SubexOutputRuneLoadState { + slot: slotMap.getRuneId(ast.slot), + next: next, + } } // Run each input Atom through a map to produce an output Atom @@ -359,7 +372,7 @@ type SubexASTSum struct { } func (ast SubexASTSum) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { if inType != ValueType || outType != ValueType { - panic("Invalid types for SubexASTNot") + panic("Invalid types for SubexASTSum") } return &SubexCaptureBeginState { next: ast.Content.compileWith(&SubexArithmeticEndState { @@ -378,7 +391,7 @@ type SubexASTProduct struct { } func (ast SubexASTProduct) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { if inType != ValueType || outType != ValueType { - panic("Invalid types for SubexASTNot") + panic("Invalid types for SubexASTProduct") } return &SubexCaptureBeginState { next: ast.Content.compileWith(&SubexArithmeticEndState { @@ -398,7 +411,7 @@ type SubexASTNegate struct { } func (ast SubexASTNegate) compileWith(next SubexState, slotMap *SlotMap, inType Type, outType Type) SubexState { if inType != ValueType || outType != ValueType { - panic("Invalid types for SubexASTNot") + panic("Invalid types for SubexASTNegate") } return &SubexCaptureBeginState { next: ast.Content.compileWith(&SubexArithmeticEndState { -- cgit v1.2.3