PageRenderTime 441ms CodeModel.GetById 156ms app.highlight 58ms RepoModel.GetById 1ms app.codeStats 21ms

/Runtime/Samples/sympl/python/parser.py

http://github.com/IronLanguages/main
Python | 755 lines | 560 code | 70 blank | 125 comment | 137 complexity | c1bec2191fbcfd273365373b747606ff MD5 | raw file
  1
  2import lexer
  3
  4### Only needed for _getOpKind
  5import clr
  6if clr.use35:
  7    clr.AddReference("Microsoft.Scripting.Core")
  8    from Microsoft.Scripting.Ast import ExpressionType
  9else:
 10    clr.AddReference("System.Core")
 11    from System.Linq.Expressions import ExpressionType
 12
 13class Parser (object):
 14    pass
 15
 16### ParseFile returns a list of top-level expressions parsed in the
 17### StreamReader.
 18###
 19def ParseFile (reader):
 20    body = []
 21    lex = lexer.Lexer(reader)
 22    token = lex.GetToken()
 23    while token is not lexer.SyntaxToken.EOF:
 24        lex.PutToken(token)
 25        body.append(_parseExpr(lex))
 26        token = lex.GetToken()
 27    return body
 28
 29### Parse returns a single expression parsed from the StreamReader.
 30###
 31def ParseExpr (reader):
 32    return _parseExpr(lexer.Lexer(reader))
 33
 34### _parseExpr parses an expression from the Lexer passed in.
 35###
 36def _parseExpr (lexr):
 37    token = lexr.GetToken()
 38    debugprint("_parseExpr: token= " + str(token))
 39    res = None
 40    if token is lexer.SyntaxToken.EOF:
 41        raise Exception("Unexpected EOF encountered while parsing expression.")
 42    if token is lexer.SyntaxToken.Quote:
 43        lexr.PutToken(token)
 44        res = _parseQuoteExpr(lexr)
 45    elif token is lexer.SyntaxToken.Paren:
 46        lexr.PutToken(token)
 47        res = _parseForm(lexr)
 48    elif isinstance(token, lexer.IdOrKeywordToken):
 49        ## If we encounter literal kwd constants, they get turned into ID
 50        ## Exprs.  Code that accepts Id Exprs, needs to check if the token is
 51        ## kwd or not when it matters.
 52        if (token.IsKeywordToken and
 53            token not in [lexer.KeywordToken.Nil, lexer.KeywordToken.True,
 54                          lexer.KeywordToken.False]):
 55            raise Exception("Keyword cannot be an expression: " + 
 56                            token.Name)
 57        else:
 58            res = SymplIdExpr(token)
 59    elif isinstance(token, lexer.LiteralToken):
 60        res = SymplLiteralExpr(token.Value)
 61    ## Check for dotted expr.
 62    if res is not None:
 63        next = lexr.GetToken()
 64        lexr.PutToken(next)
 65        if next is lexer.SyntaxToken.Dot:
 66            return _parseDottedExpr(lexr, res)
 67        else:
 68            return res
 69    raise Exception("Unexpected token when expecting "+ 
 70                    "beginning of expression -- " + str(token) + " ... " +
 71                    repr([lexr.GetToken(), lexr.GetToken(),
 72                          lexr.GetToken(), lexr.GetToken(),
 73                          lexr.GetToken(), lexr.GetToken()]))
 74
 75### _parseForm parses a parenthetic form.  If the first token after the paren
 76### is a keyword, then it something like defun, loop, if, try, etc.  If the
 77### first sub expr is another parenthetic form, then it must be an expression
 78### that returns a callable object.
 79###
 80def _parseForm (lexr):
 81    debugprint("IN parseform:")
 82    token = lexr.GetToken()
 83    if token is not lexer.SyntaxToken.Paren:
 84        raise Exception("List expression must start with '('.")
 85    token = lexr.GetToken()
 86    debugprint("first form token: " + str(token))
 87    if isinstance(token, lexer.IdOrKeywordToken):
 88        lexr.PutToken(token)
 89        debugprint("parseform: " + str(token))
 90        if token.IsKeywordToken:
 91            # Defun, Let, Set, Import, ...
 92            return _parseKeywordForm(lexr)
 93        else:
 94            return _parseFunctionCall(lexr)
 95    #elif token is lexer.SyntaxToken.Paren:
 96    #    lexr.PutToken(token)
 97    #    return _parseFunctionCall(lexr)
 98    else:
 99        lexr.PutToken(token)
100        return _parseFunctionCall(lexr)
101        
102        ## What else could start a function call?  Any Expr?
103        #raise Exception("Sympl form must have ID or keyword as first element." +
104        #                "  Got " + str(token))
105
106### _parseKeywordForm parses parenthetic built in forms such as defun, if, loop,
107### etc.
108###
109def _parseKeywordForm (lexr):
110    debugprint("IN parse kwd form:")
111    name = lexr.GetToken()
112    if not isinstance(name, lexer.KeywordToken):
113        raise Exception("Internal error: parsing keyword form?")
114    lexr.PutToken(name)
115    if name is lexer.KeywordToken.Import:
116        return _parseImport(lexr)
117    elif name is lexer.KeywordToken.Defun:
118        return _parseDefun(lexr)
119    elif name is lexer.KeywordToken.Lambda:
120        return _parseLambda(lexr)
121    elif name is lexer.KeywordToken.Set:
122        return _parseSet(lexr)
123    elif name is lexer.KeywordToken.LetStar:
124        return _parseLetStar(lexr)
125    elif name is lexer.KeywordToken.Block:
126        return _parseBlock(lexr)
127    elif name is lexer.KeywordToken.Eq:
128        return _parseEq(lexr)
129    elif name is lexer.KeywordToken.Cons:
130        return _parseCons(lexr)
131    elif name is lexer.KeywordToken.List:
132        return _parseListCall(lexr)
133    elif name is lexer.KeywordToken.If:
134        return _parseIf(lexr)
135    elif name is lexer.KeywordToken.Loop:
136        return _parseLoop(lexr)
137    elif name is lexer.KeywordToken.Break:
138        return _parseBreak(lexr)
139    elif name is lexer.KeywordToken.New:
140        return _parseNew(lexr)
141    elif name is lexer.KeywordToken.Elt:
142        return _parseElt(lexr)
143    elif (name is lexer.KeywordToken.Add or name is lexer.KeywordToken.Subtract or
144          name is lexer.KeywordToken.Multiply or name is lexer.KeywordToken.Divide or
145          name is lexer.KeywordToken.Equal or name is lexer.KeywordToken.NotEqual or
146          name is lexer.KeywordToken.GreaterThan or 
147          name is lexer.KeywordToken.LessThan or
148          name is lexer.KeywordToken.And or name is lexer.KeywordToken.Or):
149        return _parseExprTreeBinaryOp(lexr)
150    elif name is lexer.KeywordToken.Not:
151        return _parseExprTreeUnaryOp(lexr)
152    raise Exception("Internal: unrecognized keyword form?")
153
154def _parseDefun (lexr):
155    token = lexr.GetToken()
156    if token is not lexer.KeywordToken.Defun:
157        raise Exception("Internal: parsing Defun?")
158    name = lexr.GetToken()
159    if not isinstance(name, lexer.IdOrKeywordToken) or name.IsKeywordToken:
160        raise Exception("Defun must have an ID for name -- " + str(token))
161    params = _parseParams(lexr, "Defun")
162    body = _parseBody(lexr, "Hit EOF in function body -- " + name.Name)
163    return SymplDefunExpr(name, params, body)
164
165def _parseLambda (lexr):
166    token = lexr.GetToken()
167    if token is not lexer.KeywordToken.Lambda:
168        raise Exception("Internal: parsing Lambda?")
169    params = _parseParams(lexr, "Lambda")
170    body = _parseBody(lexr, "Hit EOF in function body -- ")
171    return SymplLambdaExpr(params, body)
172
173### _parseParams parses sequence of vars for Defuns and Lambdas, and always
174### returns a list of IdTokens.
175###
176def _parseParams (lexr, definer):
177    token = lexr.GetToken()
178    if token is not lexer.SyntaxToken.Paren:
179        raise Exception(definer + " must have param list following keyword.")
180    lexr.PutToken(token)
181    return _ensureListOfIds(_parseList(lexr, "param list.").Elements, False,
182                            definer + " params must be valid IDs.")
183
184### _parseBody parses sequence of expressions as for Defun, Let, etc., as well
185### as args to fun call.  This always returns a list, even if empty.  It
186### gobbles the close paren too.
187###
188def _parseBody (lexr, errmsg):
189    body = []
190    token = lexr.GetToken()
191    while (token is not lexer.SyntaxToken.EOF and
192           token is not lexer.SyntaxToken.CloseParen):
193        lexr.PutToken(token)
194        body.append(_parseExpr(lexr))
195        token = lexr.GetToken()
196    if token is lexer.SyntaxToken.EOF:
197        raise Exception(errmsg)
198    return body
199
200
201### (import id[.id]*  [{id | (id [id]*)}  [{id | (id [id]*)}]]  )
202### (import file-or-dotted-Ids name-or-list-of-members reanme-or-list-of)
203###
204def _parseImport (lexr):
205    if lexr.GetToken() is not lexer.KeywordToken.Import:
206        raise Exception("Internal error: parsing Import call?")
207    ns_or_module = _parseImportNameOrModule(lexr)
208    members = _parseImportNames(lexr, "member names", True)
209    as_names = _parseImportNames(lexr, "renames", False)
210    if lexr.GetToken() is not lexer.SyntaxToken.CloseParen:
211        raise Exception("Expected close paren for Import call.")
212    if (len(members) != len(as_names)) and (len(as_names) != 0):
213        raise Exception("Import as-names must be same form as member names.")
214    return SymplImportExpr(ns_or_module, members, as_names)
215
216### Parses dotted namespaces or Sympl.Globals members to import.
217###
218def _parseImportNameOrModule (lexr):
219    token = lexr.GetToken()
220    if not isinstance(token, lexer.IdOrKeywordToken): # Keywords are ok here.
221        raise Exception("Id must follow Import symbol.")
222    dot = lexr.GetToken()
223    if dot is lexer.SyntaxToken.Dot:
224        lexr.PutToken(dot)
225        tmp = _parseDottedExpr(lexr, SymplIdExpr(token))
226        ns_or_module = []
227        for e in [tmp.ObjectExpr] + tmp.Exprs:
228            if not isinstance(e, SymplIdExpr): # Keywords are ok here too.
229                raise Exception("Import targets must be dotted identifiers " +
230                                "only -- " + str(e) + str(ns_or_module))
231            ns_or_module.append(e.IdToken)
232        token = lexr.GetToken()
233    else:
234        ns_or_module = [token]
235        token = dot
236    lexr.PutToken(token)
237    return ns_or_module
238
239### Parses list of member names to import from the object represented in the
240### result of _parseImportNameOrModule, which will be a file module or object
241### from Sympl.Globals.
242###
243def _parseImportNames (lexr, nameKinds, allowKeywords):
244    token = lexr.GetToken()
245    debugprint("IN parseimport: " + str(token))
246    if (isinstance(token, lexer.IdOrKeywordToken) and 
247        not token.IsKeywordToken):
248        names = [token]
249    elif token is lexer.SyntaxToken.Paren:
250        lexr.PutToken(token)
251        names = _parseList(lexr, "Import " + nameKinds + ".")
252        names = _ensureListOfIds(names.Elements, allowKeywords,
253                                   "Import " + nameKinds + " must be valid IDs.")
254    elif token is lexer.SyntaxToken.CloseParen:
255        names = []
256        lexr.PutToken(token)
257    else:
258        raise Exception("Import takes dotted names, then member vars.")
259    return names
260
261def _ensureListOfIds (lst, allowKeywords, error_str):
262    for elt in lst:
263        if (not isinstance(elt, lexer.IdOrKeywordToken) or
264            (not allowKeywords and elt.IsKeywordToken)):
265            raise Exception(error_str)
266    return lst
267
268### _parseDottedExpr gathers infix dotted member access expressions.  The
269### object expression can be anything and is passed in via expr.  Successive
270### member accesses must be dotted identifier expressions or member invokes --
271### a.b.(c 3).d.  The member invokes cannot have dotted expressions for the
272### member name such as a.(b.c 3).
273###
274def _parseDottedExpr (lexr, expr):
275    debugprint("IN parse dotted:")
276    obj_expr = expr
277    token = lexr.GetToken()
278    debugprint("parse dotted: " + str(token))
279    if token is not lexer.SyntaxToken.Dot:
280        raise Exception("Internal error: parsing dotted expressions?")
281    exprs = []
282    token = lexr.GetToken()
283    is_paren = token is lexer.SyntaxToken.Paren
284    is_id = isinstance(token, lexer.IdOrKeywordToken) # Keywords ok as members.
285    while (is_id or is_paren):
286        ## Need to be fun call or IDs
287        if is_id:
288            expr = SymplIdExpr(token)
289        else:
290            lexr.PutToken(token)
291            expr = _parseForm(lexr)
292            if ((not isinstance(expr, SymplFunCallExpr)) or
293                (not isinstance(expr.Function, SymplIdExpr))):
294                raise Exception("Dotted expressions must be identifiers or " +
295                                "function calls with identiers as the function " +
296                                "value --" + str(expr))
297        exprs.append(expr)
298        token = lexr.GetToken()
299        if token is not lexer.SyntaxToken.Dot:
300            break
301        token = lexr.GetToken()
302        is_paren = token is lexer.SyntaxToken.Paren
303        is_id = isinstance(token, lexer.IdOrKeywordToken)
304    lexr.PutToken(token)
305    return SymplDottedExpr(obj_expr, exprs)
306
307### _parseSet parses a LHS expression and value expression.  All analysis on
308### the LHS is in etgen.py.
309###
310def _parseSet (lexr):
311    if lexr.GetToken() is not lexer.KeywordToken.Set:
312        raise Exception("Internal error: parsing Set?")
313    lhs = _parseExpr(lexr)
314    val = _parseExpr(lexr)
315    if lexr.GetToken() is not lexer.SyntaxToken.CloseParen:
316        raise Exception("Expected close paren for Set expression.")
317    return SymplAssignExpr(lhs, val)
318
319### _parseLetStar parses (let* ((<var> <expr>)*) <body>).
320###
321def _parseLetStar (lexr):
322    if lexr.GetToken() is not lexer.KeywordToken.LetStar:
323        raise Exception("Internal error: parsing Let?")
324    token = lexr.GetToken()
325    if token is not lexer.SyntaxToken.Paren:
326        raise Exception("Let expression has no bindings?  Missing '('.")
327    ## Get bindings
328    bindings = []
329    token = lexr.GetToken()
330    while token is lexer.SyntaxToken.Paren:
331        var = _parseExpr(lexr)
332        if not isinstance(var, SymplIdExpr) or var.IdToken.IsKeywordToken:
333            raise Exception("Let* binding must be (<ID> <expr>) -- " +
334                            str(var))
335        init = _parseExpr(lexr)
336        bindings.append((var.IdToken, init))
337        token = lexr.GetToken()
338        if token is not lexer.SyntaxToken.CloseParen:
339            raise Exception("Let binding missing close paren -- " +
340                            str(token))
341        token = lexr.GetToken()
342    if token is not lexer.SyntaxToken.CloseParen:
343        raise Exception("Let* bindings missing close paren.")
344    body = _parseBody(lexr, "Unexpected EOF in Let.")
345    return SymplLetStarExpr(bindings, body)
346
347### _parseBlock parses a block expression, a sequence of exprs to
348### execute in order, returning the last expression's value.
349###
350def _parseBlock (lexr):
351    if lexr.GetToken() is not lexer.KeywordToken.Block:
352        raise Exception("Internal error: parsing Block?")
353    body = _parseBody(lexr, "Unexpected EOF in Block.")
354    return SymplBlockExpr(body)
355
356### first sub form must be expr resulting in callable, but if it is dotted expr,
357### then eval the first N-1 dotted exprs and use invoke member or get member
358### on last of dotted exprs so that the 2..N sub forms are the arguments to
359### the invoke member.  It's as if the call breaks into a block of a temp
360### assigned to the N-1 dotted exprs followed by an invoke member (or a get
361### member and call, which the runtime binder decides).  The non-dotted expr
362### simply evals to an object that better be callable with the supplied args,
363### which may be none.
364### 
365def _parseFunctionCall (lexr):  
366    debugprint("IN parse fun call:")
367    ## First sub expr is callable object or invoke member expr.
368    fun = _parseExpr(lexr)
369    if ((type(fun) is SymplDottedExpr) and
370        (not isinstance(fun.Exprs[-1], SymplIdExpr))): #Keywords ok as members.
371        raise Exception("Function call with dotted expression for function " +
372                        "must end with ID Expr, not member invoke. " +
373                        str(fun.Exprs[-1]))
374    ## Tail exprs are args.
375    args = _parseBody(lexr, "Unexpected EOF in arg list for " + str(fun))
376    return SymplFunCallExpr(fun, args)
377
378### This parses a quoted list, ID/keyword, or literal.
379###
380def _parseQuoteExpr (lexr):
381    token = lexr.GetToken()
382    if token is not lexer.SyntaxToken.Quote:
383        raise Exception("Internal: parsing Quote?.")
384    token = lexr.GetToken()
385    if token is lexer.SyntaxToken.Paren:
386        lexr.PutToken(token)
387        expr = _parseList(lexr, "quoted list.")
388    elif (isinstance(token, lexer.IdOrKeywordToken) or
389          isinstance(token, lexer.LiteralToken)):
390        expr = token
391    else:
392        raise Exception("Quoted expression can only be list, ID/Symbol, or " +
393                        "literal.")
394    return SymplQuoteExpr(expr)
395
396def _parseEq (lexr):
397    token = lexr.GetToken()
398    if token is not lexer.KeywordToken.Eq:
399        raise Exception("Internal: parsing Eq?")
400    left, right = _parseBinaryRuntimeCall(lexr)
401    return SymplEqExpr(left, right)
402    
403def _parseCons (lexr):
404    token = lexr.GetToken()
405    if token is not lexer.KeywordToken.Cons:
406        raise Exception("Internal: parsing Cons?")
407    left, right = _parseBinaryRuntimeCall(lexr)
408    return SymplConsExpr(left, right)
409
410### _parseBinaryRuntimeCall parses two exprs and a close paren, returning the
411### two exprs.
412###
413def _parseBinaryRuntimeCall (lexr):
414    left = _parseExpr(lexr)
415    right = _parseExpr(lexr)
416    if lexr.GetToken() is not lexer.SyntaxToken.CloseParen:
417        raise Exception("Expected close paren for binary op or eq call.")
418    return (left, right)
419
420### _parseListCall parses a call to the List built-in keyword form that takes
421### any number of arguments.
422###
423def _parseListCall (lexr):
424    token = lexr.GetToken()
425    if token is not lexer.KeywordToken.List:
426        raise Exception("Internal: parsing List call?")
427    args = _parseBody(lexr, "Unexpected EOF in arg list for call to List.")
428    return SymplListCallExpr (args)
429
430def _parseIf (lexr):
431    token = lexr.GetToken()
432    if token is not lexer.KeywordToken.If:
433        raise Exception("Internal: parsing If?")
434    args = _parseBody(lexr, "Unexpected EOF in If form.")
435    argslen = len(args)
436    if argslen == 2:
437        return SymplIfExpr(args[0], args[1], None)
438    elif argslen == 3:
439        return SymplIfExpr(args[0], args[1], args[2])
440    else:
441        raise Exception("IF must be (if <test> <consequent> [<alternative>]).")
442    
443### _parseLoop parses a loop expression, a sequence of exprs to
444### execute in order, forever.  See Break for returning expression's value.
445###
446def _parseLoop (lexr):
447    if lexr.GetToken() is not lexer.KeywordToken.Loop:
448        raise Exception("Internal error: parsing Loop?")
449    body = _parseBody(lexr, "Unexpected EOF in Loop.")
450    return SymplLoopExpr(body)
451
452### _parseBreak parses a Break expression, which has an optional value that
453### becomes a loop expression's value.
454###
455def _parseBreak (lexr):
456    if lexr.GetToken() is not lexer.KeywordToken.Break:
457        raise Exception("Internal error: parsing Break?")
458    token = lexr.GetToken()
459    if token == lexer.SyntaxToken.CloseParen:
460        value = None
461    else:
462        lexr.PutToken(token)
463        value = _parseExpr(lexr)
464        token = lexr.GetToken()
465        if token != lexer.SyntaxToken.CloseParen:
466            raise Exception("Break expression missing close paren.")
467    return SymplBreakExpr(value)
468
469### Parse a New form for creating instances of types.  Second sub expr (one
470### after kwd New) evals to a type.
471###
472### Consider adding a new kwd form generic-type-args that could be the third
473### sub expr and take any number of sub exprs that eval to types.  These could
474### be used to specific concrete generic type instances.  Without this support
475### SymPL programmers need to open code this as the examples show.
476###
477def _parseNew (lexr):  
478    debugprint("IN new call:")
479    token = lexr.GetToken()
480    if token is not lexer.KeywordToken.New:
481        raise Exception("Internal: parsing New?")
482    typ = _parseExpr(lexr)
483    args = _parseBody(lexr, "Unexpected EOF in arg list for New" + str(typ))
484    return SymplNewExpr(typ, args)
485
486
487def _parseElt (lexr):
488    token = lexr.GetToken()
489    if token is not lexer.KeywordToken.Elt:
490        raise Exception("Internal: parsing Elt?")
491    obj = _parseExpr(lexr)
492    indexes = _parseBody(lexr, "Unexpected EOF in arg list for call to Elt.")
493    return SymplEltExpr(obj, indexes)
494  
495
496### _parseExprTreeBinaryOp handles operators that map to ET node kinds, but it
497### doesn't handle Eq.  We could fold that in here, but it is harder to do in C#.
498###
499def _parseExprTreeBinaryOp (lexr):
500    token = lexr.GetToken()
501    if (token is lexer.KeywordToken.Add or token is lexer.KeywordToken.Subtract or
502        token is lexer.KeywordToken.Multiply or token is lexer.KeywordToken.Divide or
503        token is lexer.KeywordToken.Equal or token is lexer.KeywordToken.NotEqual or
504        token is lexer.KeywordToken.GreaterThan or 
505        token is lexer.KeywordToken.LessThan or
506        token is lexer.KeywordToken.And or token is lexer.KeywordToken.Or):
507        pass
508    else:
509        raise Exception("Internal: parsing Binary?")
510    left, right = _parseBinaryRuntimeCall(lexr)
511    return SymplBinaryExpr(_getOpKind(token), left, right)
512
513def _parseExprTreeUnaryOp (lexr):
514    token = lexr.GetToken()
515    if token is not lexer.KeywordToken.Not:
516        raise Exception("Internal: unrecognized unary op")
517    operand = _parseExpr(lexr)
518    if lexr.GetToken() is not lexer.SyntaxToken.CloseParen:
519        raise Exception("Expected close paren for unary op call.")
520    return SymplUnaryExpr(_getOpKind(token), operand)
521
522def _getOpKind (token):
523    if token is lexer.KeywordToken.Add:
524        return ExpressionType.Add
525    if token is lexer.KeywordToken.Subtract:
526        return ExpressionType.Subtract
527    if token is lexer.KeywordToken.Multiply:
528        return ExpressionType.Multiply
529    if token is lexer.KeywordToken.Divide:
530        return ExpressionType.Divide
531    if token is lexer.KeywordToken.Equal:
532        return ExpressionType.Equal
533    if token is lexer.KeywordToken.NotEqual:
534        return ExpressionType.NotEqual
535    if token is lexer.KeywordToken.GreaterThan:
536        return ExpressionType.GreaterThan
537    if token is lexer.KeywordToken.LessThan:
538        return ExpressionType.LessThan
539    if token is lexer.KeywordToken.And:
540        return ExpressionType.And
541    if token is lexer.KeywordToken.Or:
542        return ExpressionType.Or
543    if token is lexer.KeywordToken.Not:
544        return ExpressionType.Not
545    raise Exception("Internal: can't map to ET node kind Op.")
546
547
548### This parses pure list and atom structure.  Atoms are IDs, strs, and nums.
549### Need quoted form of dotted exprs, quote, etc., if want to have macros one
550### day.  This is used for Import name parsing, Defun/Lambda params, and quoted
551### lists.
552###
553def _parseList (lexr, errStr):
554    debugprint("IN parse list")
555    token = lexr.GetToken()
556    if token is not lexer.SyntaxToken.Paren:
557        raise Exception("List expression must start with '('.")
558    token = lexr.GetToken()
559    res = []
560    while ((token != lexer.SyntaxToken.EOF) and
561           (token != lexer.SyntaxToken.CloseParen)):
562        lexr.PutToken(token)
563        elt = None
564        if token is lexer.SyntaxToken.Paren:
565            elt = _parseList(lexr, errStr)
566        elif (isinstance(token, lexer.IdOrKeywordToken) or
567              isinstance(token, lexer.LiteralToken)):
568            elt = token
569            lexr.GetToken()
570        elif  token is lexer.SyntaxToken.Dot:
571            raise Exception("Can't have dotted syntax in " + errStr)
572        else:
573            raise Exception("Unexpected token in list -- " + repr(token))
574        if elt is None:
575            raise Exception("Internal: no next element in list?")
576        res.append(elt)
577        token = lexr.GetToken()
578    if token is lexer.SyntaxToken.EOF:
579        raise Exception("Unexpected EOF encountered while parsing list.")
580    return SymplListExpr(res)
581
582
583
584#####################
585### SymplExpr Classes
586#####################
587
588class SymplExpr (object):
589    pass
590
591### SymplIdExpr represents identifiers, but the IdToken can be a keyword
592### sometimes.  For example, in quoted lists, import expressions, and as
593### members of objects in dotted exprs.  Need to check for .IsKeywordToken
594### when it matters.
595###
596class SymplIdExpr (SymplExpr):
597    def __init__ (self, id):
598        self.IdToken = id
599    def __repr__ (self):
600        return "<IdExpr " + self.IdToken.Name + ">"
601
602class SymplListExpr (SymplExpr):
603    def __init__ (self, subexprs):
604        ## subexprs is always a list of tokens or SymplListExprs.
605        self.Elements = subexprs
606    def __repr__ (self):
607        return "<ListExpr " + str(self.Elements) + ">"
608
609class SymplFunCallExpr (SymplExpr):
610    def __init__ (self, fun, args):
611        self.Function = fun
612        ## args is always a list.
613        self.Arguments = args
614    def __repr__ (self):
615        return ("<Funcall ( " + repr(self.Function) + " " +
616                repr(self.Arguments) + " )>")
617
618class SymplDefunExpr (SymplExpr):
619    def __init__ (self, name, params, body):
620        self.Name = name
621        ## params and body are always lists.
622        self.Params = params
623        self.Body = body
624    def __repr__ (self):
625        return ("<Defun " + str(self.Name) + " (" +
626                repr(self.Params) + ") ...>")
627
628class SymplLambdaExpr (SymplExpr):
629    def __init__ (self, params, body):
630        ## params and body are always lists.
631        self.Params = params
632        self.Body = body
633    def __repr__ (self):
634        return ("<Lambda " + " (" + repr(self.Params) + ") ...>")
635
636### Used to represent numbers and strings, but not Quote.
637class SymplLiteralExpr (SymplExpr):
638    def __init__ (self, val):
639        self.Value = val
640    def __repr__ (self):
641        return "<LiteralExpr " + str(self.Value) + ">"
642
643class SymplDottedExpr (SymplExpr):
644    def __init__ (self, obj, exprs):
645        self.ObjectExpr = obj
646        ## exprs is always a list of SymplIdExprs or SymplFunCallExprs,
647        ## ending with a SymplIdExpr when used as SymplFunCallExpr.Function.
648        self.Exprs = exprs
649    def __repr__ (self):
650        return ("<DotExpr " + str(self.ObjectExpr) + " . " + str(self.Exprs)
651                + " >")
652
653class SymplImportExpr (SymplExpr):
654    def __init__ (self, ns_or_module, members, as_names):
655        ## All properties are always lists.
656        self.NamespaceExpr = ns_or_module
657        self.MemberNames = members
658        self.Renames = as_names
659
660class SymplAssignExpr (SymplExpr):
661    def __init__ (self, lhs, value):
662        self.Location = lhs
663        self.Value = value
664
665class SymplLetStarExpr (SymplExpr):
666    def __init__ (self, vars, body):
667        ## bindings and body are always lists.
668        self.Bindings = vars # List of tuples: (idtoken, expr)
669        self.Body = body
670    def __repr__ (self):
671        return ("<Let* (" + repr(self.Bindings) + ") ...)>")
672
673class SymplBlockExpr (SymplExpr):
674    def __init__ (self, body):
675        ## body is always a list of SymplExpr.
676        self.Body = body
677    def __repr__ (self):
678        return ("<Block ...)>")
679
680class SymplEltExpr (SymplExpr):
681    def __init__ (self, obj, indexes):
682        self.ObjectExpr = obj
683        self.Indexes = indexes
684
685class SymplQuoteExpr (SymplExpr):
686    def __init__ (self, expr):
687        ## Expr must be SymplListExpr, SymplIdExpr, or SymplLIteralExpr
688        self.Expr = expr
689
690class SymplEqExpr (SymplExpr):
691    def __init__ (self, left, right):
692        self.Left = left
693        self.Right = right
694
695class SymplConsExpr (SymplExpr):
696    def __init__ (self, left, right):
697        self.Left = left
698        self.Right = right
699
700class SymplListCallExpr (SymplExpr):
701    def __init__ (self, args):
702        self.Elements = args
703
704class SymplIfExpr (SymplExpr):
705    def __init__ (self, test, consequent, alternative):
706        self.Test = test
707        self.Consequent = consequent
708        self.Alternative = alternative
709
710class SymplLoopExpr (SymplExpr):
711    def __init__ (self, body):
712        ## body is always a list of SymplExpr.
713        self.Body = body
714    def __repr__ (self):
715        return ("<Loop ...)>")
716
717class SymplBreakExpr (SymplExpr):
718    def __init__ (self, value):
719        ## SymplExpr or None.
720        self.Value = value
721    def __repr__ (self):
722        return ("<Break ...)>")
723
724class SymplNewExpr (SymplExpr):
725    def __init__ (self, fun, args):
726        self.Typ = fun
727        ## args is always a list.
728        self.Arguments = args
729    def __repr__ (self):
730        return ("<New ( " + repr(self.Typ) + " " +
731                repr(self.Arguments) + " )>")
732
733class SymplBinaryExpr (SymplExpr):
734    def __init__ (self, op, left, right):
735        self.Op = op
736        self.Left = left
737        self.Right = right
738
739class SymplUnaryExpr (SymplExpr):
740    def __init__ (self, op, operand):
741        self.Operand = operand
742        self.Op = op
743
744
745
746##################
747### Dev-time Utils
748##################
749
750_debug = False
751def debugprint (*stuff):
752    if _debug:
753        for x in stuff:
754            print x,
755        print