Skip to content

Commit

Permalink
Add more to Core (including tests); improvements to the monad and JSO…
Browse files Browse the repository at this point in the history
…N parser examples
  • Loading branch information
Zoetermeer committed Jul 19, 2016
1 parent 4bb4543 commit 4609dd2
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 15 deletions.
39 changes: 33 additions & 6 deletions examples/json/parser.l
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
module Result {
module MonadInfix {
fun >>=(Ok(x), f) = f(x)
fun >>=(err, _) = err

fun return(x) = Ok(x)

partition{e, t} => fun(Result{e, t}[]) : %(e[], t[])
fun partition([

packResults{e, t} => fun(Result{e, t}[]) : Result{e, t}
fun packResults([]) = Ok([])
fun packResults(r :: rs) =
switch (r) {
case Ok(x) ->
}
}
}

module Json {
import Core
import Result.MonadInfix

type Field = %(String, Value)

Expand Down Expand Up @@ -40,6 +60,12 @@ module Json {


fun read(input) {
lex(input) >>= fun(%(token, input')) =
switch (token) {
case TokEof() -> Ok([])
case _ -> Ok(
}

def tResult = lex(input)
switch (tResult) {
case Ok(%(token, input')) -> {
Expand All @@ -53,8 +79,8 @@ module Json {
}


fun parse-array(ts) {
def rv = parse-value(ts)
fun parseArray(ts) {
def rv = parseValue(ts)
switch (rv) {
case Ok(%(value, t :: ts')) -> {
switch (t) {
Expand All @@ -67,17 +93,18 @@ module Json {
}


fun parse-value([]) = Ok(JsonNull())
fun parse-value(t :: ts) {
fun parseValue([]) = Ok(%(JsonNull(), []))
fun parseValue(t :: ts) {
switch (t) {
case TokLBracket() -> parse-array(ts)
case TokLBracket() -> parseArray(ts)
case TokNull -> Ok(%(JsonNull(), ts))
}
}


fun parse(input) {
def rv = parse-value(read(input))
read(input) >>= fun(tokens) =
parseValue(tokens) >>= fun(rv) =
switch (rv) {
case Ok(%(v, _)) -> Ok(v)
case Error(msg) -> Error(msg)
Expand Down
8 changes: 8 additions & 0 deletions examples/monads/result.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Result {
module MonadInfix {
fun >>=(Ok(x), f) = f(x)
fun >>=(err, _) = err

fun return(x) = Ok(x)
}
}
31 changes: 28 additions & 3 deletions lib/Core.l
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,47 @@ module Core {
fun id(v) = v

module List {
length{a} => fun(a[]) : Int
fun length([]) = 0
fun length(x::xs) = 1 + length(xs)


fun ++([], bs) = bs
fun ++(as, []) = as
fun ++(a::as, bs) = a :: (as ++ bs)

fun ([]).at-index(_) = Nothing()
fun (x::_).at-index(0) = Just(x)
fun (_::xs).at-index(n) = xs.at-index(n - 1)

fun ([]).atIndex(_) = Nothing()
fun (x::_).atIndex(0) = Just(x)
fun (_::xs).atIndex(n) = xs.atIndex(n - 1)


each{a} => fun(fun(a) : Unit, a[]) : Unit
fun each(_, []) = ()
fun each(f, x::xs) {
f(x)
each(f, xs)
}


foldr{a, b} => fun(fun(a, b) : b, b, a[]) : b
fun foldr(f, a, x::xs) = f(x, foldr(f, a, xs))
fun foldr(f, a, []) = a


select{a} => fun(fun(a) : Bool, a, %(a[], a[])) : %(a[], a[])
fun select(p, x, %(ts, fs)) =
cond {
case p(x) -> %(x :: ts, fs)
case _ -> %(ts, x :: fs)
}


partition{a} => fun(fun(a) : Bool, a[]) : %(a[], a[])
fun partition(p, xs) {
def selector = fun(x, pr) = select(p, x, pr)
foldr(selector, %([], []), xs)
}
}
}

Expand Down
18 changes: 18 additions & 0 deletions tests/core.rkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#lang at-exp racket

(module+ test
(require "common.rkt"
rackunit)

(test-case "partition"
(check-equal?
@interp{
import Core.List

fun isFiveChars(str) = length(str) == 5

partition(
isFiveChars, ["he", "hello", "world", "foo", "bar", "fubar"])
}
@line{%(["hello", "world", "fubar"], ["he", "foo", "bar"])})))

12 changes: 6 additions & 6 deletions tests/interpreter.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -560,16 +560,16 @@
4))

(test-case "it exports algebraic data type constructors"
(check-equal?
(check-regexp-match
#px"fun x\\d* => Int -> IntOption"
@interp{
module Prims {
type IntOption =
| Just(Int)
| None
}
Prims.Just
}
@line{fun x125 => Int -> IntOption}))
}))

(test-case "it constructs ADT instances"
(check-equal?
Expand Down Expand Up @@ -885,11 +885,11 @@
@line{%(1, 2)}))

(test-case "it evaluates anonymous lambda expressions"
(check-equal?
(check-regexp-match
#px"fun x\\d* => Int -> Int -> Int"
@interp{
fun(x, y) { x + y }
}
@line{fun x122 => Int -> Int -> Int}))
}))

(test-case "it evaluates anonymous function application"
(check-equal?
Expand Down

0 comments on commit 4609dd2

Please sign in to comment.