Skip to content

Commit

Permalink
Aha\! Macros, commands, and functions are all very similar. Replaced …
Browse files Browse the repository at this point in the history
…commands with begingroup/endgroup primitives, which the parser enforces balance for. Functions to come as extended macros... nullary macros will act as always, macros with parens will act as functions.
  • Loading branch information
gatesphere committed Jan 8, 2014
1 parent 8302473 commit ccbc53f
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 15 deletions.
4 changes: 2 additions & 2 deletions examples/readme_example.silica
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ pl >> x2 play s2
pl

## let's define a command... a command is a macro with embedded structure... you'll see
hat = play rp play lp play
hat >> begingroup play rp play lp play endgroup
hat

## now let's make a longer piece using hat
hat3 = hat rp hat lp hat
hat3 >> begingroup hat rp hat lp hat endgroup
hat3

## now, a function (notice, macros, commands, and functions all share a namespace)
Expand Down
4 changes: 4 additions & 0 deletions modules/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ def primitives():
sg.new_primitive('pushstate', 'Pushes the current state of the note onto the statestack.', lambda sg: sg.note.pushstate())
sg.new_primitive('popstate', 'Pops the top state off the statestack and applies it to the note.', lambda sg: sg.note.popstate())
sg.new_primitive('removestate', 'Removes the top state off the statestack without applying it to the note.', lambda sg: sg.note.removestate())
# for now...
sg.new_primitive('begingroup', 'Used to mark the beginning of a group.', lambda sg: '{')
sg.new_primitive('endgroup', 'Used to mark the end of a group.', lambda sg: '}')
#@+node:peckj.20131224101941.5056: ** metacommands
def metacommands():
def exit(sg):
Expand Down Expand Up @@ -285,6 +288,7 @@ def run():
sg.new_macro('R', 'rest')
sg.new_macro('HAT', 'p rp p lp p')
sg.new_macro('STAIRS3', 'p rp p rp p rp')
sg.new_macro('HATCMD', 'begingroup p rp p lp p endgroup')
return True
#@-others
#@-leo
8 changes: 6 additions & 2 deletions silica/core/note.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ def pop_alphabet(self, relative=False):
#@+node:peckj.20140106082417.4635: *4* state
#@+node:peckj.20140106082417.4636: *5* pushstate
def pushstate(self):
state = self.makestate()
self.statestack.append(state)
return None
#@+node:peckj.20140108090613.4236: *5* makestate
def makestate(self):
state = {'scale': self.scale[:], # copy, not store-by-ref
'degree': self.degree,
'duration': self.duration,
Expand All @@ -200,8 +205,7 @@ def pushstate(self):
'instrument': self.instrument,
'deltadegree': self.deltadegree,
'prevregister': self.prevregister}
self.statestack.append(state)
return None
return state
#@+node:peckj.20140106082417.4637: *5* popstate
def popstate(self):
if len(self.statestack) > 0:
Expand Down
18 changes: 17 additions & 1 deletion silica/core/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ def __init__(self):
'metacommand': self.run_metacommand,
'macro': self.run_macro}
self.mcmode = False
self.notestate = None
#@+node:peckj.20131222154620.7092: *3* reset_parsing_state
def reset_parsing_state(self):
self.mcmode = False
self.notestate = None
#@+node:peckj.20131221180451.4203: *3* parse_line # stub
def parse_line(self, string, reset=True):
if reset: self.reset_parsing_state()
if string.startswith('-'):
self.mcmode = True
self.notestate = sg.note.makestate() # to recover from errors without affecting note.statestack
toks = string.split()
out = []
for tok in toks:
Expand All @@ -36,7 +39,20 @@ def parse_line(self, string, reset=True):
except Exception as e:
continue # token doesn't exist -- ignore it
out = ' '.join(out)
return out
if self.groups_are_balanced(out):
return out
else:
sg.note.applystate(self.notestate)
return 'Error: groups not fully balanced.'
#@+node:peckj.20140108090613.4237: *4* groups_are_balanced
def groups_are_balanced(self, out):
pushchars = ['{']
popchars = ['}']
stack = []
for c in out:
if c in pushchars: stack.append(c)
if c in popchars and stack[-1] == pushchars[popchars.index(c)]: stack.pop()
return len(stack) == 0
#@+node:peckj.20131222154620.7073: *3* run_primitive
def run_primitive(self, p):
if self.mcmode:
Expand Down
18 changes: 8 additions & 10 deletions silica/silica.leo
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<v t="peckj.20131219081918.4174"><vh>Tester</vh>
<v t="peckj.20131219081918.4175"><vh>@file ../silicaTester.py</vh></v>
</v>
<v t="peckj.20130604112211.2148" a="E"><vh>silica</vh>
<v t="peckj.20130604112211.2148"><vh>silica</vh>
<v t="peckj.20130604112211.2146"><vh>@file __init__.py</vh></v>
<v t="peckj.20130604112211.2149" a="E"><vh>@path core</vh>
<v t="peckj.20130604112211.2147"><vh>@file __init__.py</vh></v>
Expand All @@ -42,10 +42,10 @@ expanded="peckj.20140106180202.4622,"><vh>@file macro.py</vh></v>
expanded="peckj.20131222154620.7082,"><vh>@file metacommand.py</vh></v>
<v t="peckj.20131218082219.4117"
expanded="peckj.20131218082219.4120,"><vh>@file mode.py</vh></v>
<v t="peckj.20131218082219.4088"
<v t="peckj.20131218082219.4088" a="E"
expanded="peckj.20131218082219.4091,peckj.20131218082219.4135,peckj.20140106082417.4635,"><vh>@file note.py</vh></v>
<v t="peckj.20131219081918.4285" a="E"
expanded="peckj.20131219081918.4288,"><vh>@file parser.py</vh></v>
expanded="peckj.20131219081918.4288,peckj.20131221180451.4203,"><vh>@file parser.py</vh></v>
<v t="peckj.20131221114825.4521" a="E"
expanded="peckj.20131221114825.4524,"><vh>@file primitive.py</vh></v>
<v t="peckj.20130604112211.2150"><vh>@file runSilica.py</vh></v>
Expand All @@ -61,16 +61,16 @@ expanded="peckj.20131219081918.4218,peckj.20131218082219.4108,peckj.201312190819
expanded="peckj.20131219081918.4271,peckj.20131219081918.4289,peckj.20131219081918.4290,peckj.20131219081918.4273,"><vh>@file repl.py</vh></v>
</v>
</v>
<v t="peckj.20131224101941.5049" a="E"><vh>modules</vh>
<v t="peckj.20131224101941.5049"><vh>modules</vh>
<v t="peckj.20131224101941.5050" a="E"><vh>@file ../modules/home.py</vh></v>
<v t="peckj.20131224101941.5051"><vh>@file ../modules/__init__.py</vh></v>
</v>
</v>
<v t="peckj.20131219081918.4173"><vh>Code (silica)</vh>
<v t="peckj.20131219081918.4173" a="E"><vh>Code (silica)</vh>
<v t="peckj.20130604112211.2170"><vh>autoexec</vh>
<v t="peckj.20130604112211.2172"><vh>@file ../autoexec.silica</vh></v>
</v>
<v t="peckj.20130604112211.2151"><vh>@path ../examples</vh>
<v t="peckj.20130604112211.2151" a="E"><vh>@path ../examples</vh>
<v t="peckj.20130604112211.2153"><vh>@edit readme_example.silica</vh></v>
<v t="peckj.20130604112211.2154"><vh>@edit glass_twopages.silica</vh></v>
<v t="peckj.20130604112211.2155"><vh>@edit john.silica</vh></v>
Expand All @@ -86,11 +86,10 @@ expanded="peckj.20131219081918.4271,peckj.20131219081918.4289,peckj.201312190819
</v>
<v t="peckj.20130604112211.2166" a="E"><vh>Docs</vh>
<v t="peckj.20131219081918.4263"><vh>required libs</vh></v>
<v t="peckj.20131221114825.4538" a="E"><vh>To implement</vh>
<v t="peckj.20131221114825.4538"><vh>To implement</vh>
<v t="peckj.20131221114825.4539"><vh>parser</vh></v>
<v t="peckj.20131224101941.5058"><vh>metacommands</vh></v>
<v t="peckj.20131221114825.4542"><vh>commands</vh></v>
<v t="peckj.20131221114825.4543"><vh>functions</vh></v>
<v t="peckj.20131221114825.4543"><vh>functions (as a part of macros)</vh></v>
<v t="peckj.20131221114825.4544"><vh>transforms</vh></v>
<v t="peckj.20131221114825.4545"><vh>repetition factors</vh></v>
<v t="peckj.20131221114825.4546"><vh>push+pop stack</vh></v>
Expand Down Expand Up @@ -136,7 +135,6 @@ Future:
<t tx="peckj.20131219081918.4265"></t>
<t tx="peckj.20131221114825.4538"></t>
<t tx="peckj.20131221114825.4539"></t>
<t tx="peckj.20131221114825.4542"></t>
<t tx="peckj.20131221114825.4543"></t>
<t tx="peckj.20131221114825.4544"></t>
<t tx="peckj.20131221114825.4545"></t>
Expand Down

0 comments on commit ccbc53f

Please sign in to comment.