Content

See the quick guide.
Please do not replicate information already contained in other reference places like Wikipedia, just link to them. Use [[[Main_Page]]] to link to wikipedia.

## Dates

send:: msg ctx.set  (d1=`now()`)

expect::  (d1 is `Date`)

send:: msg ctx.set  (d1=`(d1 + "1s")`)

expect::  (d1 is `Date`)
send:: msg ctx.set  (d1=`(now() + "1 s")`)

expect::  (d1 is `Date`)
send:: msg ctx.set  (d1=`(d1 + "1 n")`)

expect::  (d1 is `Date`)
send:: msg ctx.set  (d1=`(d1 + "1 m")`)

expect::  (d1 is `Date`)
send:: msg ctx.set  (d1=`(d1 + "1 h")`)

expect::  (d1 is `Date`)
send:: msg ctx.set  (d1=`(d1 + "1 d")`)

expect::  (d1 is `Date`)
send:: msg ctx.set  (d1=`(d1 + "1M")`)

expect::  (d1 is `Date`)
send:: msg ctx.set  (d1=`(d1 + "1 y")`)

expect::  (d1 is `Date`)

send:: msg ctx.set  (d1=`(now() - "1 second")`, d2=`(now() + "1 second")`)

expect::  (d1 < `d2`)
expect:: NOT (d1 > `d2`)
expect::  ( `(((d1 > d2)) is false)`)

# Simple expressions

## Setting a variable

`ctx.set` is used to set one or more variables in the current context:

send:: msg ctx.set  (res=`"123"`=`"123"`)

expect::  (res is `"123"`)

`ctx.setVal` is useful if the name is itself sourced, a variable:

send:: msg ctx.setVal  (name=`"res"`=`"res"`, value:Number=`"321"`=`321`)

expect::  (res is `321`)
expect::  (res is `number`)

`ctx.echo` shows all the details about the input arguments - use it to see types, values etc:

send:: msg ctx.echo  (res12=`"123"`=`"123"`)

expect::  (res12 is `"123"`)

Contains:

send:: msg ctx.set  (res23=`"123"`=`"123"`)

expect::  (res23 contains `"2"`)
expect::  (res23 containsNot `"4"`)

## encoders

send:: msg ctx.base64encode  (res29=`"res29"`=`"res29"`)

expect::  (payload is `"cmVzMjk="`)

send:: msg ctx.base64decode  (res29=`payload`)

expect::  ( `((payload as string) is "res29")`)

send:: msg ctx.sha1  (res35=`"res35"`=`"res35"`)

expect::  (payload is `"7D509433920201DF3A7EE4363970D83359D826B8"`)
expect::  (res35_sha1 is `"7D509433920201DF3A7EE4363970D83359D826B8"`)

send:: msg ctx.sha256  (res35=`"res35"`=`"res35"`)

expect::  (payload is `"2e994a1eb4aea52f7c059c6b82f05f14777575371f3acf833ef72fb7e294ac71"`)
expect::  (res35_sha256 is `"2e994a1eb4aea52f7c059c6b82f05f14777575371f3acf833ef72fb7e294ac71"`)

## Resetting a value

This will remove a value from the context:

send:: msg ctx.setVal  (name=`"res"`=`"res"`)

expect::  (res not `defined`)

Reset the entire context, with `ctx.clear`:

send:: msg ctx.setVal  (name=`"res"`=`"res"`, value:Number=`"321"`=`321`)

expect::  (res is `321`)

send:: msg ctx.clear

expect::  (res not `defined`)

## Constants

Examples of constants of different types:

send:: msg ctx.set  (res:Number=`"45"`=`45`)

expect::  (res is `45`)
expect::  (res is `number`)

send:: msg ctx.set  (res=`"astra"`=`"astra"`)

expect::  (res is `"astra"`)
expect::  (res is `string`)

String interpolation and escaping of such

send:: msg ctx.set  (interpol=`"x"`=`"x"`)

send:: msg ctx.set  (int1=`"\${interpol}"`)

expect::  (int1 contains `"x"`)
send:: msg ctx.set  (int1=`"a\${interpol}b"`)

expect::  (int1 contains `"x"`)
send:: msg ctx.set  (int1=`"\$\${interpol}"`)

expect::  (int1 containsNot `"x"`)
send:: msg ctx.set  (int1=`"a\$\${interpol}b"`)

expect::  (int1 containsNot `"x"`)

## Simple expressions

The usual simple expressions are available and they are type aware:

send:: msg ctx.set  (ai:Number=`"1"`=`1`, bi:Number=`"2"`=`2`)

send:: msg ctx.set  (as=`"1"`=`"1"`, bs=`"2"`=`"2"`)

send:: msg ctx.set  (res53=`(ai + bi)`)

expect::  (res53 is `3`)
send:: msg ctx.set  (res56=`(as + bs)`)

expect::  (res56 is `"12"`)

## Precendence and associativity

send:: msg ctx.set  (res52:Number=`(((1 - 2) + (3 * 4)) + 9)`)

expect::  (res52 is `20`)

### String functions

send:: msg ctx.set  (res57=```"1 2 3 "```=```"1 2 3 "```)

expect::  (res57:Array)
expect::  (res57[="length"] is `6`)
expect::  ( `((res57[="length"] + 5) is 11)`)
expect::  ( `((sizeOf(res57.lines) + 4) is 7)`)
send:: msg ctx.set  (l66=`res57[="lines"]`)

## Template expansion

By default all strings are templatized in expressions, using `\${...}` to match a simpler expression:

send:: msg ctx.setVal  (name=`"template1"`=`"template1"`, value=`"is\${1+2}"`)

expect::  (template1 is `"is3"`)

Use this to configure environment settings like URLs for instance

send:: msg ctx.set  (HOST =`"https://www.google.c"`...=`"https://www.google.ca"`)

send:: msg ctx.echo  (url=`"\${HOST}/search?q=dieselapps"`)

expect::  (url is `"https://www.google.ca/search?q=dieselapps"`)
expect::  ( `("\${HOST}/" is "https://www.google.ca/")`)

## Javascript and regex

These are not used: send:: msg ctx.set  (a:Number=`"1"`=`1`, b:Number=`"2"`=`2`)

The input parameters overwrite context above send:: msg expr.js.sum1  (a:Number=`"1"`=`1`, b:Number=`"2"`=`2`)

expect::  (res39 is `3`)

send:: msg expr.js.sum2  (a:Number=`"1"`=`1`, b:Number=`"2"`=`2`)

expect::  (res42 is `3.0`)

send:: msg expr.js.name1  (email=`"jane@doe.com"`=`"jane@doe.com"`)

expect::  (res40 is `"jane"`)

/\$send ctx.setVal (name="cart", value={})

send:: msg expr.js.validateEmail  (email=`"jane@doe.com"`=`"jane@doe.com"`)

expect::  (ok25 is `true`)

send:: msg ctx.set  (ok25:Boolean=`false`)

send:: msg expr.js.validateEmail  (email=`"janedoe.com"`=`"janedoe.com"`)

expect::  (ok25 is `false`)

### Regex and string built-in functions

send:: msg ctx.set  (re176=`matches(a:String="abc"="abc",b:String="[abc]+"="[abc]+")`)

expect::  (re176 is `true`)

send:: msg ctx.set  (re176=`matches(a:String="abc"="abc",b:String="[bc]+"="[bc]+")`)

expect::  (re176 is `false`)

send:: msg ctx.set  (re176=`replaceAll(a:String="abczbc"="abczbc",b:String="[bc]+"="[bc]+",c:String="xx"="xx")`)

expect::  (re176 is `"axxzxx"`)

send:: msg ctx.set  (re185=`replaceFirst(a:String="abczbc"="abczbc",b:String="[bc]+"="[bc]+",c:String="xx"="xx")`)

expect::  (re185 is `"axxzbc"`)

send:: msg ctx.set  (res188=`trim(a:String=" abc "=" abc ")`)

expect::  (res188 is `"abc"`)

## Sourcing and checking values

send:: msg expr.source.erase

expect::  (erased not `defined`)

send:: msg ctx.set  (val192=`""`)

expect::  (val192 is `defined`)
expect::  (val192 not `undefined`)
expect::  (val192 is `empty`)
expect::  (val192 not `nzlen`)

send:: msg ctx.set  (val198:Undefined=null)

expect::  (val198 not `defined`)
expect::  (val198 is `undefined`)
expect::  (val198 is `empty`)
expect::  (val198 not `nzlen`)

send:: msg ctx.set  (val204=`"abcd"`=`"abcd"`)

expect::  (val204 is `defined`)
expect::  (val204 not `undefined`)
expect::  (val204 not `empty`)
expect::  (val204 is `nzlen`)

## The diesel object:

send:: msg ctx.set  (res5=`js{{ diesel.engineId() }}`)

expect::  (res5 not `empty`)

send:: msg ctx.set  (res139=`js{{ diesel.env() }}`)

expect::  (res139 not `empty`)

## The wix object:

send:: msg ctx.set  (res144=`js{{ wix.diesel.env }}`)

expect::  (res144 not `empty`)

## Boolean expressions

send:: msg ctx.set  (b1:Boolean=`true`)

expect::  (b1 is `true`)
expect::  (b1 not `false`)
expect::  (b1)
expect::  (b1)\$ifc::true
expect::  (b1)\$ifc::b1
expect::  (b1)\$ifc::(b1 is true)
expect::  (b1)\$ifc::(b1 not false)

send:: msg expr.bool.test1

expect::  (b2)
expect::  (b3 is `true`)
expect::  (b4)
expect::  (b5 not `defined`)

send:: msg expr.bool.test1nos

expect::  (b2n)
expect::  (b3n is `true`)
expect::  (b4n)
expect::  (b5n not `defined`)

send:: msg expr.bool.test2  (a:Number=`"1"`=`1`, b:Number=`"2"`=`2`)

expect::  (b23)
expect::  (b26)

send:: msg expr.bool.test2  (a:Number=`"2"`=`2`, b:Number=`"1"`=`1`)

expect::  (b22)
expect::  (b25)

send:: msg expr.bool.test2  (a:Number=`"2"`=`2`, b:Number=`"2"`=`2`)

expect::  (b24)
expect::  (b25)
expect::  (b26)

send:: msg expr.bool.testAllExpr  (a:Number=`"1"`=`1`, bb:Number=`"2"`=`2`)

expect::  (b > `23`)

send:: msg expr.bool.testContains  (a=`"123"`=`"123"`)

expect::  (b94 is `true`)
expect::  (b95 is `true`)

send:: msg expr.bool.testAndUndef

expect::  (b47 not `defined`)
expect::  (b48 is `true`)
expect::  (b49 not `defined`)
expect::  (b50 not `defined`)
expect::  (b51 is `true`)

send:: msg expr.bool.testBra1

expect::  (bb105 is `true`)

send:: msg expr.int.lt

## Arrays, Lists and range accessors

Range accessor on Strings

send:: msg ctx.set  (l3=`"012345"`=`"012345"`)

From index to end send:: msg ctx.set  (l4=`l3[:Range=0..None]`)

expect::  (l4 is `"012345"`)

From index toindex send:: msg ctx.set  (l8=`l3[:Range=0..Some(3)]`)

expect::  (l8 is `"0123"`)

From index to one before end (last index if negative is relative to the end) send:: msg ctx.set  (l11=`l3[:Range=0..Some(-1)]`)

expect::  (l11 is `"01234"`)

Both ends relative to the end send:: msg ctx.set  (l14=`l3[:Range=-2..Some(-1)]`)

expect::  (l14 is `"34"`)

TODO why is this expected?

send:: msg ctx.set  (l14=`l3[:Range=-1..None]`)

expect::  (l14 is `"45"`)

Range accessor on Lists

send:: msg ctx.set  (l21:Array=`[0,1,2,3,4,5]`)

send:: msg ctx.set  (l4=`l21[:Range=0..None]`)

expect::  (l4 is `[0,1,2,3,4,5]`)

send:: msg ctx.set  (l8=`l21[:Range=0..Some(3)]`)

expect::  (l8 is `[0,1,2,3]`)

send:: msg ctx.echo  (l11=`l21[:Range=0..Some(-1)]`)

expect::  (l11 is `[0,1,2,3,4]`)

send:: msg ctx.set  (l239:Array=`[]`)

expect::  (l239 is `[]`)

Accessor in pmatch /expect

send:: msg ctx.set  (l14=`l21[:Range=-2..Some(-1)]`)

expect::  (l14[="1"=1] is `4`)

send:: msg ctx.set  (state281:JSON=`{source:[0,1,2,3,4,5],dest:[],aux:[]}`)

expect::  (state281[="source"="source"][="0"=0] == `0`)

send:: msg ctx.set  (state281:JSON=`{source:[0,1,2,3,4,5],dest:[],aux:[]}`)

expect::  (state281[="source"="source"][="0"=0] is `0`)

## Setters and accessors

send:: msg test.ctxAccessor

expect::  (payload is `( (90 + 87) )`)

json in context and array sum

send:: msg ctx.set  (state294:JSON=`{source:[0,1,2,3,4,5],dest:[],aux:[]}`)

send:: msg test.jsonAccessorSet  (source=`"source"`=`"source"`, dest=`"dest"`=`"dest"`, aux=`"aux"`=`"aux"`)

expect::  (state294[="source"] is `[1,2,3,4,5]`)
expect::  (state294[="dest"] is `[0]`)

## Expansion

val a217=`"a217v"`=`"a217v"` send:: msg ctx.set  (a218=`"\${a217}"`)

expect::  (a218 is `"a217v"`)

## Capture groups

send:: msg expr.captureGroups  (path=`"/getAccount1/67"`=`"/getAccount1/67"`)

expect::  (payload[="accountId"] is `"67"`)

send:: msg ctx.set  (payload=`"/getAccount1/99"`=`"/getAccount1/99"`)

send:: msg ctx.regex  (regex =`"/getAccount1/(?<acct"`...=`"/getAccount1/(?<acctId3>\d+)"`)

expect::  (acctId3 is `"99"`)

Don't overwrite payload: send:: msg ctx.set  (payload=`"pa"`=`"pa"`)

send:: msg ctx.regex  (regex =`"/getAccount1/(?<acct"`...=`"/getAccount1/(?<acctId4>\d+)"`, payload=`"/getAccount1/999"`=`"/getAccount1/999"`)

expect::  (acctId4 is `"999"`)
expect::  (payload is `"pa"`)

## Javascript expressions

Simple javascript - script is independent (no arguments):

send:: msg ctx.set  (a225=`js{{ 1+4 }}`)

expect::  (a225 is `5`)

Escaping quotes with javascript regex (notice a230 available inside the js expression):

val a230=`"{"a":32}"`=`"{"a":32}"` send:: msg ctx.set  (a231=`js{{ a230.replace(/"/g, "\"") }}`)

expect::  (a231 is `"{&quot;a&quot;:32}"`)

More JS examples:

send:: msg ctx.set  (now=`js{{ java.lang.System.currentTimeMillis() }}`)

// \$send ctx.set( // later=js:{var d = new Date(); d.setSeconds(d.getSeconds() + 10); return d.toISOString();} // ) send:: msg ctx.set  (later=`js{{ var d = new Date(); d.setSeconds(d.getSeconds() + 10); d.toISOString(); }}`)

send:: msg ctx.set  (noweh=`js{{ var d = new Date(); d.toISOString(); }}`, later=`js{{ var d = new Date(); d.setSeconds(d.getSeconds() + 10); d.toISOString(); }}`)

expect::  (now is `number`)

## Precedence

### As

send:: msg ctx.set  (a=`(("1234" + "5") as Number)`)

expect::  (a is `12345`)

val p15=`"p15"`=`"p15"` val p16=`(("p16-" + p15) as "application/pdf")` send:: msg ctx.echo  (a=`p16`)

expect::  ( `(typeOf(p16) is "application/pdf")`)
expect::  (p16 is `"p16-p15"`)

as a variable

val p366=`"Number"`=`"Number"` send:: msg ctx.set  (a=`(("1234" + "5") as p366)`)

expect::  (a is `12345`)

### Filter

send:: msg ctx.set  (a:Array=`([1,2,3] filter ( x=>(x > 1)() ))`)

expect::  (a is `[2,3]`)

### Map

send:: msg ctx.set  (a278:Array=`([1,2,3] map ( x=>(x + 1)() ))`)

expect::  (a278 is `[2,3,4]`)

TODO this is stuck in parm evaluation on second pass

// .orElse(cur.find(a => a.name == name && a.hasCurrentValue)) // or is it the static value? // \$send ctx.set( a401 = [1,2] map (x=> expr.oper.sumnump (a=x,b=2) ) ) // \$expect (a401 is [3,4])

Both filter and map

TODO these work with ExprParser1

send:: msg ctx.set  (a281:Array=`(([1,2,3] filter ( x=>(x > 1)() )) map ( x=>(x + 1)() ))`)

expect::  (a281 is `[3,4]`)

send:: msg ctx.set  (a284:Array=`((([1,2] + [3]) filter ( x=>(x > 1)() )) map ( x=>(x + 1)() ))`)

expect::  (a284 is `[3,4]`)

send:: msg ctx.set  (a287:Array=`(([1,2,3] filter ( x=>((((x - (1 * 1)) + 1) > 1) or (2 > 4))() )) map ( x=>(x + 1)() ))`)

expect::  (a287 is `[3,4]`)

TODO this is not working

// \$send ctx.set( a290 = [1,2,3] filter (x=> js:{(x - 1*1 + 1) > 1}) map (x=> x + 1) ) // \$expect (a290 is [3,4])

Convert to string and use a JS expression for filter lambda send:: msg ctx.set  (a298:Array=`(([1,2,3] filter ( x=>(x > 1)() )) map ( x=>(x + "")() ))`)

send:: msg ctx.echo  (res299=`(res57[="lines"] filter e=>js{{ !a298.contains(e) }}())`)

expect::  (res299 is `["1"]`)

### Map on range

TODO implement map on range - range to be basic ttype

// \$send ctx.set( a452 = 1..3 map (x=> x + 1) ) // \$expect (a281 is [3,4])

## Expressions in messages

send:: msg expr.oper.sumnum  (a:Number=`"1"`=`1`, b:Number=`"2"`=`2`)

expect::  (res is `3`)
send:: msg expr.oper.sumnum2  (a:Number=`"1"`=`1`)

expect::  (res is `3`)
send:: msg expr.oper.sumnum3  (a:Number=`"1"`=`1`)

expect::  (res is `3`)

send:: msg expr.oper.sumstr  (first=`"Jane"`=`"Jane"`, last=`"Doe"`=`"Doe"`)

expect::  (res is `"Jane Doe"`)

## sizeOf

send:: msg ctx.set  (a358:Array=`[1,2,3]`)

send:: msg ctx.echo  (x=`sizeOf(a358)`)

expect::  ( `(sizeOf(a358) > 0)`)

send:: msg test.diesel.condif

expect::  (b138 is `true`)

## Special cases

Just making sure this parsed:

send:: msg dieseltest.expr151  (env:Number=`"123"`=`123`)

expect::  (res151 >= `1`)

## Bugs

send:: msg testdiesel.bug.overwritectxname  (payload=`"a"`=`"a"`, a=`"a"`=`"a"`)

expect::  (payload is `"z"`)

send:: msg testdiesel.bug.overwritectxname  (payload=`"a"`=`"a"`, a=`"a"`=`"a"`)

expect::  (payload is `"z"`)

This was an issue - setting and then expanding in a submessage bug

send:: msg test.diesel.testSetExpand

expect::  (yy is `"123"`)

0 \$mock:: test.diesel.testSetExpand
ctx.set (YY=`"123"`=`"123"`)
ctx.set (yy=`"\${YY}"`)
diesel.step (desc =`""should have expande"`...=`"should have expanded by now - running a js regex to mess it up if not expanded"`)
diesel.step (desc =`""otherwise the expec"`...=`"otherwise the expect will evaluate it and it works..."`)
. (`yy`=`js{{ yy.replace(/\$/g, "xx") }}`)

## FUnctions

val x477:Array=`[]` send:: msg ctx.echo  (x472=`accessor(obj=x477[="0"=0],accessor:String="a.b.c"="a.b.c")`)

expect::  (x472 is `undefined`)

## Last line parse test

send:: msg testdiesel.lastline

expect::  (payload contains `"end of line is parsed here..."`)

MAKE SURE THERE IS NO \n after this line 0 \$mock:: testdiesel.lastline
. (`payload`=`"end of line is parsed here..."`)

## Arrays

val query:JSON=`{key:"elf"}` send:: msg ctx.set  (y=`(query map ( x=>(((x[="key"] + ":"") + x[="value"]) + """)() ))`)

send:: msg ctx.echo  (x=`(y mkString " AND ")`)

expect::  (x contains `"elf"`)

## setting should work the same in all scopes:

0 \$mock:: z.v
. (`x`=`[]`)
. (`y`=`x[="0"=0]`)
. (`ctx[="y1"]`=`x[="0"=0]`)
. (`dieselScope[="y2"]`=`x[="0"=0]`)
. (`dieselRoot[="y3"]`=`x[="0"=0]`)
. (`dieselRealm[="y4"]`=`x[="0"=0]`)

send:: msg z.v

expect::  (y not `defined`)
expect::  (y1 is `undefined`)
expect::  (y2 is `undefined`)
expect::  (y3 is `undefined`)
expect::  (dieselRealm[="y4"] is `undefined`)

0 \$mock:: z.v1
. (`x`=`[5]`)
. (`y`=`x[="0"=0]`)
. (`ctx[="y1"]`=`x[="0"=0]`)
. (`dieselScope[="y2"]`=`x[="0"=0]`)
. (`dieselRoot[="y3"]`=`x[="0"=0]`)
. (`dieselRealm[="y4"]`=`x[="0"=0]`)

send:: msg z.v1

expect::  (y is `5`)
expect::  (y1 is `5`)
expect::  (y2 is `5`)
expect::  (y3 is `5`)
expect::  (dieselRealm[="y4"] is `5`)

## Long int numbers

send:: msg ctx.set  (x:Number=`"3179699189"`=`3179699189`)

expect::  (x is `number`)
expect::  (x > `55`)

## Proper number type and others

send:: msg ctx.set  (s572=`sprintf(a:String="%d"="%d",b:Number="44"=44)`)

send:: msg ctx.set  (s573=`sprintf(a:String="%.1f"="%.1f",b:Number="44.0"=44.0)`)

send:: msg ctx.set  (s574=`sprintf(a:String="%.1f"="%.1f",b:Number=(44 * 1.0))`)

expect::  (s572 is `"44"`)
expect::  (s573 is `"44.0"`)
expect::  (s574 is `"44.0"`)