PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

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

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