Skip to content

Commit

Permalink
(!! lib syn) Use brackets-based cPaws
Browse files Browse the repository at this point in the history
We're ahead-of-spec here (and therefore spec-incompliant, I suppose, heh.) This doesn't bother me, as a change from braces to brackets is basically a given at this point. It'll probably be snuck into the next release of the specification.
  • Loading branch information
ELLIOTTCABLE committed Jul 3, 2014
1 parent f639de0 commit 58fa5d8
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 113 deletions.
10 changes: 5 additions & 5 deletions Examples/02.world.singleton.factory.bean.paws
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#!/usr/bin/env paws.js --no-start
implementation void()
implementation void[]

-- Let's try an unnecessarily complex approach to printing something. We'll save it into the data-
graph, and then read it back out to print it:

( infrastructure execution stage()
(infrastructure affix() (locals)) Hi! )
[ infrastructure execution stage[]
[infrastructure affix[] [locals]] Hi! ]

( infrastructure execution stage()
(implementation console inspect) (infrastructure unaffix() (locals)) )
[ infrastructure execution stage[]
[implementation console inspect] [infrastructure unaffix[] [locals]] ]
34 changes: 17 additions & 17 deletions Examples/03.a.wild.local.variable.appears.paws
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
#!/usr/bin/env paws.js --no-start
implementation void()
implementation void[]

-- It's useful to store state, right? Here we'll create a new name for something, by storing it in
an assignment-pair on `locals`.

( infrastructure execution stage()
(infrastructure affix() (locals))
(infrastructure empty()) )
( infrastructure execution stage()
(infrastructure own() (locals))
(infrastructure length() (locals)) )
[ infrastructure execution stage[]
[infrastructure affix[] [locals]]
[infrastructure empty[]] ]
[ infrastructure execution stage[]
[infrastructure own[] [locals]]
[infrastructure length[] [locals]] ]

( infrastructure execution stage()
(infrastructure affix()
(infrastructure get() (locals) (infrastructure length() (locals))))
# )
( infrastructure execution stage()
(infrastructure affix()
(infrastructure get() (locals) (infrastructure length() (locals))))
(infrastructure) )
[ infrastructure execution stage[]
[infrastructure affix[]
[infrastructure get[] [locals] [infrastructure length[] [locals]]]]
# ]
[ infrastructure execution stage[]
[infrastructure affix[]
[infrastructure get[] [locals] [infrastructure length[] [locals]]]]
[infrastructure] ]

( # execution stage()
(implementation console print) Go!.PAWS! )
[ # execution stage[]
[implementation console print] Go!.PAWS! ]
124 changes: 62 additions & 62 deletions Examples/04.The.Great.Definition.paws
Original file line number Diff line number Diff line change
@@ -1,93 +1,93 @@
#!/usr/bin/env paws.js --no-start
implementation void()
implementation void[]

-- Let's combine some of our examples so far, and put them towards the task of creating a new
procedure of code that we can call by its name.


-- First, we'll provide a short-name to reference `infrastructure`, to abbreviate our code,
( infrastructure execution stage()
(infrastructure affix() (locals) )
(infrastructure empty() ) )
( infrastructure execution stage()
(infrastructure own() (locals) )
(infrastructure length() (locals) ) )

( infrastructure execution stage()
(infrastructure affix()
(infrastructure get() (locals) (infrastructure length() (locals))) )
# )
( infrastructure execution stage()
(infrastructure affix()
(infrastructure get() (locals) (infrastructure length() (locals))) )
(infrastructure) )
[ infrastructure execution stage[]
[infrastructure affix[] [locals] ]
[infrastructure empty[] ] ]
[ infrastructure execution stage[]
[infrastructure own[] [locals] ]
[infrastructure length[] [locals] ] ]

[ infrastructure execution stage[]
[infrastructure affix[]
[infrastructure get[] [locals] [infrastructure length[] [locals]]] ]
# ]
[ infrastructure execution stage[]
[infrastructure affix[]
[infrastructure get[] [locals] [infrastructure length[] [locals]]] ]
[infrastructure] ]


-- Next, we store our actual routine in the `locals`.
( # execution stage() (# affix() (locals)) (# empty()) )
( # execution stage() (# own() (locals)) (# length() (locals)) )
( # execution stage()
(# affix() (# get() (locals) (# length() (locals))) )
my.routine )
( # execution stage()
(# affix() (# get() (locals) (# length() (locals))) )
{ implementation console print Phew,that.worked. } )
[ # execution stage[] [# affix[] [locals]] [# empty[]] ]
[ # execution stage[] [# own[] [locals]] [# length[] [locals]] ]
[ # execution stage[]
[# affix[] [# get[] [locals] [# length[] [locals]]] ]
my.routine ]
[ # execution stage[]
[# affix[] [# get[] [locals] [# length[] [locals]]] ]
{ implementation console print Phew,that.worked. } ]


-- Next, we want to access the `my.routine locals`, but we can't get that by combining, because
the combination-receiver for `execution`s would *stage* it. Instead, we're going to extract the
`thing` receiver, and manually invoke it with a receiver-parameters object.

-- So here, we construct a parameters object to get a reference to `locals` out of the receiver:
( # execution stage() (# affix() (locals)) (# empty()) )
( # execution stage() (# own() (locals)) (# length() (locals)) )
( # execution stage()
(# affix() (# get() (locals) (# length() (locals))) )
parameters )
( # execution stage()
(# affix() (# get() (locals) (# length() (locals))) )
(# empty()) )

( # execution stage() (# set() (parameters) 1)() )
( # execution stage() (# set() (parameters) 2)(my.routine) )
( # execution stage() (# set() (parameters) 3)locals )
[ # execution stage[] [# affix[] [locals]] [# empty[]] ]
[ # execution stage[] [# own[] [locals]] [# length[] [locals]] ]
[ # execution stage[]
[# affix[] [# get[] [locals] [# length[] [locals]]] ]
parameters ]
[ # execution stage[]
[# affix[] [# get[] [locals] [# length[] [locals]]] ]
[# empty[]] ]

[ # execution stage[] [# set[] [parameters] 1][] ]
[ # execution stage[] [# set[] [parameters] 2][my.routine] ]
[ # execution stage[] [# set[] [parameters] 3]locals ]


-- Now we get an arbitrary `thing`'s receiver, and invoke it with our parameters.
( # execution stage() (# affix() (locals)) (# empty()) )
( # execution stage() (# own() (locals)) (# length() (locals)) )
( # execution stage()
(# affix() (# get() (locals) (# length() (locals))) )
my.locals )
( # execution stage()
(# affix() (# get() (locals) (# length() (locals))) )
(# receiver() (# empty())
(parameters) ) )
[ # execution stage[] [# affix[] [locals]] [# empty[]] ]
[ # execution stage[] [# own[] [locals]] [# length[] [locals]] ]
[ # execution stage[]
[# affix[] [# get[] [locals] [# length[] [locals]]] ]
my.locals ]
[ # execution stage[]
[# affix[] [# get[] [locals] [# length[] [locals]]] ]
[# receiver[] [# empty[]]
[parameters] ] ]


-- Finally, the reason for all that madness: we need to get `implementation` and `infrastructure`
into our routine's `locals`, since they're only injected into our environment at this root level.
( # execution stage() (# affix() (my.locals)) (# empty()) )
( # execution stage() (# own() (my.locals)) (# length() (my.locals)) )
( # execution stage()
(# affix() (# get() (my.locals) (# length() (my.locals))) )
infrastructure )
( # execution stage()
(# affix() (# get() (my.locals) (# length() (my.locals))) )
(infrastructure) )
[ # execution stage[] [# affix[] [my.locals]] [# empty[]] ]
[ # execution stage[] [# own[] [my.locals]] [# length[] [my.locals]] ]
[ # execution stage[]
[# affix[] [# get[] [my.locals] [# length[] [my.locals]]] ]
infrastructure ]
[ # execution stage[]
[# affix[] [# get[] [my.locals] [# length[] [my.locals]]] ]
[infrastructure] ]

( # execution stage() (# affix() (my.locals)) (# empty()) )
( # execution stage() (# own() (my.locals)) (# length() (my.locals)) )
( # execution stage()
(# affix() (# get() (my.locals) (# length() (my.locals))) )
implementation )
( # execution stage()
(# affix() (# get() (my.locals) (# length() (my.locals))) )
(implementation) )
[ # execution stage[] [# affix[] [my.locals]] [# empty[]] ]
[ # execution stage[] [# own[] [my.locals]] [# length[] [my.locals]] ]
[ # execution stage[]
[# affix[] [# get[] [my.locals] [# length[] [my.locals]]] ]
implementation ]
[ # execution stage[]
[# affix[] [# get[] [my.locals] [# length[] [my.locals]]] ]
[implementation] ]


-- And now, the reveal:

( # execution stage() (my.routine)() )
[ # execution stage[] [my.routine][] ]

-- Yay! <3
10 changes: 5 additions & 5 deletions Source/data.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Paws.Thing = Thing = parameterizable class Thing
#
# For instance, given `{foo: thing_A, bar: thing_B}` will be constructed into the following:
#
# (, (, ‘foo’, thing_B), (, ‘bar’, thing_B))
# [, [, ‘foo’, thing_B], [, ‘bar’, thing_B]]
#
# The ‘pair-ish’ values are always owned by the generated structure; as are, by default, the objects
# passed in. The latter is overridable with `.with(responsible: no)`.
Expand Down Expand Up @@ -347,17 +347,17 @@ Thing.inspectID = (it)-> it.id.slice(-8)

Thing::toString = ->
output = Thing.inspectID(this) + (if @name? then ': '+T.bold @name else '')
if @_?.tag == no then output else '['+(@constructor.__name__ or @constructor.name)+' '+output+']'
if @_?.tag == no then output else '<'+(@constructor.__name__ or @constructor.name)+' '+output+'>'

Thing::inspect = ->
@toString()

Label::toString = ->
output = ''+@alien+'' + (if @name? then ': '+T.bold @name else '')
if @_?.tag == no then output else '['+(@constructor.__name__ or @constructor.name)+' '+output+']'
if @_?.tag == no then output else '<'+(@constructor.__name__ or @constructor.name)+' '+output+'>'

Execution::toString = ->
output = Thing.inspectID(this) +
(if @name? then ': '+T.bold @name else '') +
(if @resumptions? then new Array(@resumptions - @bits.length).join('()') else '')
if @_?.tag == no then output else '['+(@constructor.__name__ or @constructor.name)+' '+output+']'
(if @resumptions? then new Array(@resumptions - @bits.length).join('[]') else '')
if @_?.tag == no then output else '<'+(@constructor.__name__ or @constructor.name)+' '+output+'>'
2 changes: 1 addition & 1 deletion Source/interactive.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ parameterizable class Interactive
inspector.append superexpr
expr = inspector
else
expr = parser.parse '<inspect> ('+code+')'
expr = parser.parse '<inspect> ['+code+']'

Paws.info "-- Generated expression to evaluate: " +
expr.with(context: yes, tag: no).toString()
Expand Down
6 changes: 3 additions & 3 deletions Source/parser.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Expression = parameterizable class Expression

# A simple recursive descent parser with no backtracking. No lexing is needed here.
class Parser
labelCharacters = /[^(){} \r\n]/ # Not currently supporting quote-delimited labels
labelCharacters = /[^\[\]{} \r\n]/ # Not currently supporting quote-delimited labels

constructor: (@text, opts = {})->
# Keep track of the current position into the text
Expand Down Expand Up @@ -73,7 +73,7 @@ class Parser
@with_range(new constructor(it), start)

# Subexpression
paren: -> @braces('()', (it)-> it)
paren: -> @braces('[]', (it)-> it)
# Execution
scope: -> @braces('{}', Paws.Native)

Expand Down Expand Up @@ -116,7 +116,7 @@ class Serializer
text += ' ' if next

if contents instanceof Expression
text += '('+@serialize(contents, '')+')'
text += '['+@serialize(contents, '')+']'
text += ' ' if next

return text unless next?
Expand Down
2 changes: 1 addition & 1 deletion Source/primitives
2 changes: 1 addition & 1 deletion Source/reactor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ advance = (response)->
# DOCME: wat.
{value, next} = @stack.pop()
@position = next
return new Combination value, upcoming.contents ? this # Special-cased self-reference, `()`
return new Combination value, upcoming.contents ? this # Special-cased self-reference, `[]`

# DOCME: wat.
{contents, next} = @position
Expand Down
24 changes: 12 additions & 12 deletions Test/parser.tests.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ describe 'Parser', ->
expect(expr.next.contents.alien.toString()).to.be('world')

it 'should parse subexpressions', ->
expr = parser.parse('(hello) (world)').next
expr = parser.parse('[hello] [world]').next
expect(expr.contents).to.be.a(parser.Expression)
expect(expr.contents.next.contents).to.be.a(Paws.Label)
expect(expr.next.contents).to.be.a(parser.Expression)
expect(expr.next.contents.next.contents).to.be.a(Paws.Label)

it 'should parse Execution', ->
expr = parser.parse('{hello world}').next
expr = parser.parse('{ hello world }').next
expect(expr.contents).to.be.a(Paws.Native)

it 'should keep track of locations', ->
Expand Down Expand Up @@ -76,7 +76,7 @@ describe 'Parser', ->
expect(world_label.source.end).to.be(11)

it 'should keep track of tricky locations', ->
expr = parser.parse(' h( a{b } )')
expr = parser.parse(' h[ a{b } ]')

contains_same = (expr)->
expect(expr.source.contents()).to.be(expr.contents.source.contents())
Expand All @@ -87,7 +87,7 @@ describe 'Parser', ->

list = hello.next
contains_same(list)
expect(list.source.contents()).to.be('( a{b } )')
expect(list.source.contents()).to.be('[ a{b } ]')

a = list.contents.next
contains_same(a)
Expand All @@ -110,28 +110,28 @@ describe 'Serializer', ->
expect(expr.serialize()).to.be ''

it 'generates no whitespace at the ends', ->
expr = parser.parse('foo (bar) baz')
expr = parser.parse('foo [bar] baz')
expect(expr.serialize()).to.not.match /^\s+|\s+$/

expr = parser.parse('foo (bar) (baz)')
expr = parser.parse('foo [bar] [baz]')
expect(expr.serialize()).to.not.match /^\s+|\s+$/

it 'generates quotes around Labels', ->
expr = parser.parse('foo')
expect(expr.serialize()).to.be '"foo"'

it 'generates parenthesis around sub-expressions', ->
expr = parser.parse('(foo)')
expect(expr.serialize()).to.be '("foo")'
expr = parser.parse('[foo]')
expect(expr.serialize()).to.be '["foo"]'

it 'puts spaces between adjacent Labels', ->
expr = parser.parse('foo bar')
expect(expr.serialize()).to.be '"foo" "bar"'

it 'puts no space inside the start or end of expressions', ->
expr = parser.parse('abc (def) ghi')
expect(expr.serialize()).to.be '"abc" ("def") "ghi"'
expr = parser.parse('abc [def] ghi')
expect(expr.serialize()).to.be '"abc" ["def"] "ghi"'

it 'handles complex nested expressions', ->
expr = parser.parse('(bar ((foo))) baz')
expect(expr.serialize()).to.be '("bar" (("foo"))) "baz"'
expr = parser.parse('[bar [[foo]]] baz')
expect(expr.serialize()).to.be '["bar" [["foo"]]] "baz"'
Loading

0 comments on commit 58fa5d8

Please sign in to comment.