99if not hasattr (__builtins__ , 'basestring' ):
1010 __builtins__ .basestring = str
1111
12+ rLinestart = re .compile ("^" , re .M )
13+ rGetParentFunctionName = re .compile ("<function ([^.]+)" )
14+
15+ def getParentFunctionName (lambda_function ):
16+ return rGetParentFunctionName .match (repr (lambda_function )).group (1 )
17+
18+ def islambda (v ):
19+ LAMBDA = lambda :0
20+ return isinstance (v , type (LAMBDA )) and v .__name__ == LAMBDA .__name__
1221
1322class Scope :
1423 def __init__ (self , parent = {}):
@@ -38,6 +47,23 @@ def __delitem__(self, key):
3847 else :
3948 del self .parent [key ]
4049
50+ def __repr__ (self ):
51+ string = "{"
52+ for key in self .lookup :
53+ value = self .lookup [key ]
54+ string += "%s: %s" % (key ,
55+ (getParentFunctionName (value ) if
56+ islambda (value ) else
57+ "" .join (list (map (str , value ))) if
58+ isinstance (value , list ) else
59+ repr (value ))
60+ )
61+ string += ", "
62+ string = string [:- 2 ] + "}"
63+ return (string +
64+ "\n " +
65+ rLinestart .sub (" " , repr (self .parent )))
66+
4167 def has (self , key ):
4268 return key in self
4369
@@ -59,9 +85,10 @@ def Inject(scope, keys, values):
5985rWhitespace = re .compile (r"[ \t]+" , re .M )
6086rNewlines = re .compile (r"[\r\n]+" , re .M )
6187rBits = re .compile (r"[01]+" )
62- rName = re .compile (r"(?!\binput\b)[A- Z_$]+" , re . I )
88+ rName = re .compile (r"(?!\binput\b|\b__scope__\b)[a-zA- Z_$]+" )
6389rRandom = re .compile (r"\?" )
6490rInput = re .compile (r"\binput\b" )
91+ rScope = re .compile (r"\b__scope__\b" )
6592rInfix = re .compile (r"[&|]" )
6693rPrefix = re .compile (r"!" )
6794rPostfix = re .compile (r"\[[ht]\]" )
@@ -84,7 +111,8 @@ def Inject(scope, keys, values):
84111 "Name" : [rName ],
85112 "Random" : [rRandom ],
86113 "Input" : [rInput ],
87- "Literal" : [["|" , "Input" , "Bits" , "Name" , "Random" ]],
114+ "Scope" : [rScope ],
115+ "Literal" : [["|" , "Input" , "Scope" , "Bits" , "Name" , "Random" ]],
88116 "Arguments" : [
89117 rOpenParenthesis ,
90118 ["?" , rName , ["*" , rComma , rName ]],
@@ -138,7 +166,8 @@ def Inject(scope, keys, values):
138166 "Condition" ,
139167 "Out" ,
140168 "Comment" ,
141- "Newlines"
169+ "Newlines" ,
170+ "Expression"
142171 ]
143172 ]
144173 ]
@@ -170,6 +199,10 @@ def Input(result):
170199 return lambda scope : [GetInput (scope )]
171200
172201
202+ def ScopeTransform (result ):
203+ return lambda scope : Print (repr (scope ))
204+
205+
173206def Literal (result ):
174207 return [result ]
175208
@@ -286,14 +319,16 @@ def GetInput(scope):
286319
287320
288321def Print (result ):
289- print ("" .join (list (map (str , result ))))
322+ if result :
323+ print ("" .join (list (map (str , result ))))
290324
291325transform = {
292326 "Newlines" : NoLambda ,
293327 "Bits" : Bits ,
294328 "Name" : Name ,
295329 "Random" : Random ,
296330 "Input" : Input ,
331+ "Scope" : ScopeTransform ,
297332 "Literal" : Literal ,
298333 "Arguments" : Arguments ,
299334 "Call Arguments" : Arguments ,
@@ -327,7 +362,7 @@ def NoTransform(token, argument):
327362 return argument
328363
329364
330- def get (code , token , process = Transform ):
365+ def Get (code , token , process = Transform ):
331366 length = 0
332367 match = rWhitespace .match (code )
333368 if match :
@@ -339,7 +374,7 @@ def get(code, token, process=Transform):
339374 rest = token [1 :]
340375 if first == "|" :
341376 for token in rest :
342- result = get (code , token , process )
377+ result = Get (code , token , process )
343378 if result [0 ] != None :
344379 return (result [0 ], result [1 ] + length )
345380 return (None , 0 )
@@ -355,7 +390,7 @@ def get(code, token, process=Transform):
355390 tokens = []
356391 success = True
357392 for token in rest :
358- gotten = get (code , token , process )
393+ gotten = Get (code , token , process )
359394 if gotten [0 ] == None :
360395 success = False
361396 break
@@ -374,7 +409,7 @@ def get(code, token, process=Transform):
374409 result = []
375410 grammar = grammars [token ]
376411 for tok in grammar :
377- gotten = get (code , tok , process )
412+ gotten = Get (code , tok , process )
378413 if gotten [0 ] == None :
379414 return (None , 0 )
380415 result += [gotten [0 ]]
@@ -390,22 +425,29 @@ def get(code, token, process=Transform):
390425 return (None , 0 )
391426
392427
393- def Run (code , input = "" , astify = False , grammar = "Program" ):
394- scope = Scope ()
428+ def Run (code = "" , input = "" , astify = False , grammar = "Program" , repl = False , scope = None ):
429+ if not scope :
430+ scope = Scope ()
431+ if repl :
432+ while repl :
433+ try :
434+ Print (Run (raw_input ("Logicode> " ), scope = scope ))
435+ except (KeyboardInterrupt , EOFError ):
436+ return
395437 scope ["input" ] = list (map (int , filter (
396438 lambda c : c == "0" or c == "1" ,
397439 input
398440 )))[::- 1 ]
399441 if astify :
400- result = get (code , grammar , NoTransform )[0 ]
442+ result = Get (code , grammar , NoTransform )[0 ]
401443 print (Astify (result ))
402444 return
403- result = get (code , grammar )[0 ]
445+ result = Get (code , grammar )[0 ]
404446 if result :
405447 program = result [0 ]
406448 for statement in program :
407- function = statement [0 ]
408- statement [ 0 ]( scope )
449+ result = statement [0 ]( scope )
450+ return result
409451
410452
411453def Astify (parsed , padding = "" ):
@@ -427,17 +469,22 @@ def Astify(parsed, padding=""):
427469 help = "Code of the program." )
428470 parser .add_argument ("-i" , "--input" , type = str , nargs = "?" , default = "" ,
429471 help = "Input to the program." )
430- parser .add_argument ("-a" , "--astify" , action = "store_true" )
472+ parser .add_argument ("-a" , "--astify" , action = "store_true" ,
473+ help = "Print AST instead of interpreting." )
474+ parser .add_argument ("-r" , "--repl" , action = "store_true" ,
475+ help = "Open as REPL instead of interpreting." )
431476 argv = parser .parse_args ()
432- if len (argv .file ):
477+ if argv .repl :
478+ Run (repl = True )
479+ elif len (argv .file ):
433480 code = ""
434481 for path in argv .file :
435482 if os .path .isfile (argv .file [0 ]):
436483 with open (argv .file [0 ]) as file :
437- code += file .read ()
484+ code += file .read () + " \n "
438485 else :
439486 with open (argv .file [0 ] + ".lgc" ) as file :
440- code += file .read ()
487+ code += file .read () + " \n "
441488 if argv .astify :
442489 Run (code , "" , True )
443490 elif argv .input :
@@ -452,9 +499,10 @@ def Astify(parsed, padding=""):
452499 else :
453500 Run (code )
454501 else :
502+ code = raw_input ("Enter program: " )
455503 if argv .astify :
456- Run (raw_input ( "Enter program: " ) , "" , True )
504+ Run (code , "" , True )
457505 elif argv .input :
458- Run (raw_input ( "Enter program: " ) , argv .input [0 ])
506+ Run (code , argv .input [0 ])
459507 else :
460- Run (raw_input ( "Enter program: " ) )
508+ Run (code )
0 commit comments