Skip to content

Commit

Permalink
Make pair type generic; naming things
Browse files Browse the repository at this point in the history
  • Loading branch information
jimbxb committed Oct 2, 2024
1 parent 199360d commit 9a5f3e2
Showing 1 changed file with 25 additions and 26 deletions.
51 changes: 25 additions & 26 deletions samples/json.wybe
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# A recursive-descent parser for JSON documents in Wybe.

pub constructors
jobject(list(pair))
jobject(list(pair(string, _)))
| jlist(list(_))
| jstring(string)
| jnumber(float)
Expand All @@ -17,9 +17,14 @@ pub def {test} (a:_ = b:_) {
}

## pair type
# A pair containing a key and a JSON value.
pub type pair {
pub pair(key:string, value:json)
# A pair containing a key and a value.
pub type pair(K, V) {
pub pair(key:K, value:V)

pub def {test} (a:_(K, V) = b:_(K, V)) {
foreign lpvm cast(a^key):int = foreign lpvm cast(b^key):int
foreign lpvm cast(a^value):int = foreign lpvm cast(b^value):int
}
}

## resource tokens
Expand Down Expand Up @@ -138,12 +143,12 @@ def {test} null(?null:_) use !tokens {
}

## sequence/4 use !tokens
# Parse a comma-separated sequence of things, with a preceding and
# Parse a comma-separated sequence of items, with a preceding and
# following character, followed by whitespace.
def {test} sequence(before:char, parse_item:{resource,test}(?X), after:char, ?xs:list(X)) use !tokens {
def {test} sequence(before:char, item:{resource,test}(?X), after:char, ?xs:list(X)) use !tokens {
!literal(before)
if { !parse_item(?x) ::
!sequence_tail(parse_item, ?xs)
if { !item(?x) ::
!sequence_tail(item, ?xs)
?xs = [x | xs]
| else ::
?xs = []
Expand All @@ -153,10 +158,10 @@ def {test} sequence(before:char, parse_item:{resource,test}(?X), after:char, ?xs

## sequence_tail/2 use !tokens
# Parse the tail of a sequnece. Helper for sequence/4.
def {test} sequence_tail(parse_item:{resource,test}(?X), ?xs:list(X)) use !tokens {
def {test} sequence_tail(item:{resource,test}(?X), ?xs:list(X)) use !tokens {
if { !literal(',') ::
!parse_item(?x)
!sequence_tail(parse_item, ?xs)
!item(?x)
!sequence_tail(item, ?xs)
?xs = [x | xs]
| else ::
?xs = []
Expand Down Expand Up @@ -292,24 +297,19 @@ def print_list(ind:int, start:char, printer:{resource}(int, X), end:char, xs:lis
# TESTING
###########

type test {
pub case(should_parse:bool, document:string)
}

?tests = [
# these should parse
case(true, "{}"),
case(true, "true"),
case(true, "[3.141596]"),
case(true, " {\"a\": [1, 1.020, 1e2, 01.2E3, false, { \"key\": null}],\n \"abc\\ndef\": true } "),
# these should fail
case(false, "definitely not JSON!"),
case(false, "\"abc"),
case(false, "{} {}")
pair(true, "{}"),
pair(true, "true"),
pair(true, "[3.141596]"),
pair(true, " {\"a\": [1, 1.020, 1e2, 01.2E3, false, { \"key\": null}],\n \"abc\\ndef\": true } "),
# these should fail to parse
pair(false, "definitely not JSON!"),
pair(false, "\"abc"),
pair(false, "{} {}")
]

for ?test in tests {
case(?should_parse, ?document) = test
for pair(?should_parse:bool, ?document) in tests {
!print("Attempting to parse ")
!escape(document)
!nl
Expand All @@ -324,4 +324,3 @@ for ?test in tests {

!nl
}

0 comments on commit 9a5f3e2

Please sign in to comment.