#Copyright (c) 2007-8, Playful Invention Company. #Permission is hereby granted, free of charge, to any person obtaining a copy #of this software and associated documentation files (the "Software"), to deal #in the Software without restriction, including without limitation the rights #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #copies of the Software, and to permit persons to whom the Software is #furnished to do so, subject to the following conditions: #The above copyright notice and this permission notice shall be included in #all copies or substantial portions of the Software. #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN #THE SOFTWARE. import re from time import clock from operator import isNumberType import random from math import sqrt class taLogo: pass from taturtle import * procstop = False class symbol: def __init__(self, name): self.name = name self.nargs = None self.fcn = None def __str__(self): return self.name def __repr__(self): return '#'+self.name class logoerror(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) def run_blocks(lc, spr, blocks): lc.stacks['stack1'] = None lc.stacks['stack2'] = None for i in blocks: if i.proto.name=='hat1': lc.stacks['stack1']= readline(lc,blocks_to_code(i)) if i.proto.name=='hat2': lc.stacks['stack2']= readline(lc,blocks_to_code(i)) code = blocks_to_code(spr) print code setup_cmd(lc, code) def blocks_to_code(spr): if spr==None: return ['%nothing%'] code = [] dock = spr.proto.docks[0] if len(dock)>4: code.append(dock[4]) if spr.proto.primname != '': code.append(spr.proto.primname) else: code.append(float(spr.label)) for i in range(1,len(spr.connections)): b = spr.connections[i] dock = spr.proto.docks[i] if len(dock)>4: for c in dock[4]: code.append(c) if b!=None: code.extend(blocks_to_code(b)) elif spr.proto.docks[i][0] not in ['flow','numend','unavailable','logi-']: code.append('%nothing%') return code def intern(lc, str): if str in lc.oblist: return lc.oblist[str] sym = symbol(str) lc.oblist[str] = sym return sym def parseline(str): split = re.split(r"\s|([\[\]()])", str) return [x for x in split if x and x != ""] def readline(lc, line): res = [] while line: token = line.pop(0) if isNumberType(token): res.append(token) elif token.isdigit(): res.append(float(token)) elif token[0]=='-' and token[1:].isdigit(): res.append(-float(token[1:])) elif token[0] == '"': res.append(token[1:]) elif token == '[': res.append(readline(lc,line)) elif token == ']': return res else: res.append(intern(lc, token)) return res def setup_cmd(lc, str): stopsignon(lc); lc.procstop=False list = readline(lc, str) lc.step = start_eval(lc, list) def start_eval(lc, list): icall(lc, evline, list); yield True yield False def evline(lc, list): oldiline = lc.iline lc.iline = list[:] lc.arglist = None while lc.iline: token = lc.iline[0] if token==lc.symopar: token=lc.iline[1] icall(lc, eval); yield True if lc.procstop: break if lc.iresult==None: continue raise logoerror(str(lc.iresult)) lc.iline = oldiline ireturn(lc); yield True def eval(lc, infixarg=False): token = lc.iline.pop(0) if type(token) == lc.symtype: icall(lc, evalsym, token); yield True res = lc.iresult else: res = token if not infixarg: while infixnext(lc): icall(lc, evalinfix, res); yield True res = lc.iresult ireturn(lc, res); yield True def evalsym(lc, token): undefined_check(lc, token) oldcfun, oldarglist = lc.cfun, lc.arglist lc.cfun, lc.arglist = token, [] if token.nargs==None: raise logoerror("#noinput") for i in range(token.nargs): no_args_check(lc) icall(lc, eval); yield True lc.arglist.append(lc.iresult) if lc.cfun.rprim: if type(lc.cfun.fcn)==lc.listtype: icall(lc, ufuncall, cfun.fcn); yield True else: icall(lc, lc.cfun.fcn, *lc.arglist); yield True result = None else: result = lc.cfun.fcn(lc, *lc.arglist) lc.cfun, lc.arglist = oldcfun, oldarglist if lc.arglist!=None and result==None: raise logoerror("%s didn't output to %s" % (oldcfun.name, lc.cfun.name)) ireturn(lc, result); yield True def evalinfix(lc, firstarg): token = lc.iline.pop(0) oldcfun, oldarglist = lc.cfun, lc.arglist lc.cfun, lc.arglist = token, [firstarg] no_args_check(lc) icall(lc, eval,True); yield True lc.arglist.append(lc.iresult) result = lc.cfun.fcn(lc,*lc.arglist) lc.cfun, lc.arglist = oldcfun, oldarglist ireturn (lc,result); yield True def infixnext(lc): if len(lc.iline)==0: return False if type(lc.iline[0])!=lc.symtype: return False return lc.iline[0].name in ['+', '-', '*', '/','%','and','or'] def undefined_check(lc, token): if token.fcn != None: return False raise logoerror("I don't know how to %s" % token.name) def no_args_check(lc): if lc.iline and lc.iline[0]!=lc.symnothing : return raise logoerror("#noinput") def prim_wait(lc,time): setlayer(lc.tw.turtle.spr,630) endtime = millis()+an_int(lc,time)*100 while millis()float(y)) defprim(lc,'less?', 2, lambda lc,x,y: float(x)