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/parse.go | 82 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 22 deletions(-) (limited to 'subex/parse.go') diff --git a/subex/parse.go b/subex/parse.go index d7fe243..619c1c3 100644 --- a/subex/parse.go +++ b/subex/parse.go @@ -1,6 +1,7 @@ package subex import ( + "fmt" "main/walk" "strconv" "strings" @@ -115,6 +116,7 @@ func parseScalarLiteral(l RuneReader) (walk.Scalar, bool) { panic("Invalid literal") } default: + fmt.Printf("%c\n", r) panic("Invalid literal") } } @@ -181,7 +183,8 @@ func parseRepeatRange(l RuneReader) (output []ConvexRange) { return output } -func parseValueReplacement(l RuneReader) (output []OutputValueAST) { +func parseValueReplacement(l RuneReader) (output SubexAST) { + output = SubexASTEmpty{} // TODO escaping // TODO add arrays, maps and strings loop: for { @@ -197,37 +200,67 @@ func parseValueReplacement(l RuneReader) (output []OutputValueAST) { if slot == eof { panic("Missing slot character") } - output = append(output, OutputValueLoadAST {slot: slot}) + output = SubexASTConcat { + First: output, + Second: SubexASTOutputValueLoad { + slot: slot, + }, + } + // TODO: destructures + case '"': + output = SubexASTConcat { + First: output, + Second: SubexASTDestructure { + Destructure: NoneStructure, + Structure: StringStructure, + Content: parseRuneReplacement(l, '"'), + }, + } default: l.Rewind() scalar, ok := parseScalarLiteral(l) if !ok { panic("Invalid scalar literal") } - output = append(output, OutputValueLiteralAST {scalar}) + output = SubexASTConcat { + First: output, + Second: SubexASTOutputValueLiteral { + literal: scalar, + }, + } } } return output } -func parseRuneReplacement(l RuneReader) (output []OutputRuneAST) { +func parseRuneReplacement(l RuneReader, end rune) (output SubexAST) { + output = SubexASTEmpty{} // TODO escaping - // TODO add arrays, maps and strings loop: for { r := l.Next() switch r { case eof: panic("Missing closing `") - case '`': + case end: break loop case '$': slot := l.Next() if slot == eof { panic("Missing slot character") } - output = append(output, OutputRuneLoadAST {slot: slot}) + output = SubexASTConcat { + First: output, + Second: SubexASTOutputRuneLoad { + slot: slot, + }, + } default: - output = append(output, OutputRuneLiteralAST {r}) + output = SubexASTConcat { + First: output, + Second: SubexASTOutputRuneLiteral { + literal: r, + }, + } } } return output @@ -394,6 +427,7 @@ func parseDestructure(l RuneReader, destructure Structure, inType Type) (lhs Sub } func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType Type) { + start: r := l.Next() switch r { case eof: @@ -467,16 +501,14 @@ func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType lhs = SubexASTCopyNumber{} case '`': outType = inType - lhs = SubexASTOutputValues {parseValueReplacement(l)} - // TODO - // case '_': - // lhs = SubexASTCopyStringAtom{} - // case '#': - // lhs = SubexASTCopyString{} - // case ',': - // lhs = SubexASTCopyValue{} - // case '"': - // lhs = SubexASTCopyScalar {walk.NewAtomStringTerminal()} + lhs = parseValueReplacement(l) + case ' ': + if inType == RuneType { + outType = RuneType + lhs = SubexASTCopyRune {' '} + } else { + goto start + } default: outType = inType if inType == RuneType { @@ -533,10 +565,16 @@ func parseSubex(l RuneReader, minPower int, inType Type) (lhs SubexAST, outType InnerOutType: outType, } } else { - resolveTypes(inType, ValueType) - lhs = SubexASTStoreValues { - Match: lhs, - Slot: slot, + if inType == ValueType { + lhs = SubexASTStoreValues { + Match: lhs, + Slot: slot, + } + } else { + lhs = SubexASTStoreRunes { + Match: lhs, + Slot: slot, + } } } outType = AnyType -- cgit v1.2.3