Translator.java 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216
  1. package kawa.lang;
  2. import gnu.mapping.*;
  3. import gnu.expr.*;
  4. import gnu.kawa.reflect.*;
  5. import gnu.bytecode.ArrayClassLoader;
  6. import gnu.bytecode.ClassType;
  7. import gnu.bytecode.Field;
  8. import gnu.bytecode.Member;
  9. import gnu.bytecode.Type;
  10. import gnu.bytecode.ZipLoader;
  11. import gnu.text.SourceMessages;
  12. import gnu.lists.*;
  13. import gnu.kawa.lispexpr.*;
  14. import java.util.*;
  15. import gnu.kawa.functions.GetNamedPart;
  16. import gnu.kawa.functions.CompileNamedPart;
  17. import gnu.kawa.functions.MakeSplice;
  18. import gnu.kawa.functions.MultiplyOp;
  19. import gnu.kawa.functions.Expt;
  20. import gnu.kawa.xml.XmlNamespace;
  21. import gnu.math.DFloNum;
  22. import gnu.math.IntNum;
  23. import gnu.math.Unit;
  24. import gnu.text.Char;
  25. import gnu.text.SourceLocator;
  26. import gnu.text.StandardNamedChars;
  27. /* #ifdef enable:XML */
  28. import gnu.xml.NamespaceBinding;
  29. /* #endif */
  30. import kawa.standard.Scheme;
  31. import kawa.standard.require.DeclSetMapper;
  32. /** Used to translate from source to Expression.
  33. * The result has macros expanded, lexical names bound, etc, and is
  34. * ready for code generation.
  35. * This is sometimes called a "compilation environment",
  36. * but we modify it as we go along - there is a single Translator for
  37. * each top-level form.
  38. */
  39. public class Translator extends Compilation
  40. {
  41. // Global environment used to look for syntax/macros.
  42. private Environment env;
  43. /** Set if we're processing (as opposed to expanding)
  44. * a <code>define-syntax</code> or <code>defmacro</code>. */
  45. public Macro currentMacroDefinition;
  46. /** Innermost current scope of pattern variable,
  47. * from a <code>syntax-case</code>. */
  48. public PatternScope patternScope;
  49. public Declaration templateScopeDecl;
  50. /** A "mark" created for the current macro application.
  51. * This is (more-or-less) the mark specified by the syntax-case
  52. * specification (in r6rs-lib), applied to the output of a transformer.
  53. * However, instead of "applying" a mark to the transformer output,
  54. * we remember in the TemplateScope an object unique to the application.
  55. */
  56. Object currentMacroMark = null;
  57. /** A variable to hold the matched values for syntax-case
  58. * pattern variables. */
  59. public Declaration matchArray;
  60. /** A stack of aliases pushed by <code>pushRenamedAlias</code>. */
  61. private Stack<Declaration> renamedAliasStack;
  62. public Object pendingForm;
  63. public LambdaExp curMethodLambda;
  64. /* #ifdef enable:XML */
  65. public NamespaceBinding xmlElementNamespaces = NamespaceBinding.predefinedXML;
  66. /* #endif */
  67. public static final Declaration getNamedPartDecl;
  68. static {
  69. // Declare the special symbol $lookup$ (from the reader)
  70. // and bind it to getNamedPartDecl.
  71. String cname = "gnu.kawa.functions.GetNamedPart";
  72. String fname = "getNamedPart";
  73. getNamedPartDecl = Declaration.getDeclarationFromStatic(cname, fname);
  74. LispLanguage.getNamedPartLocation.setDeclaration(getNamedPartDecl);
  75. }
  76. private static Expression errorExp = new ErrorExp ("unknown syntax error");
  77. public Translator(Language language, SourceMessages messages,
  78. NameLookup lexical, Environment env) {
  79. super(language, messages, lexical);
  80. this.env = env;
  81. }
  82. public Translator(Language language, SourceMessages messages,
  83. NameLookup lexical) {
  84. super(language, messages, lexical);
  85. this.env = Environment.getCurrent();
  86. }
  87. @Override
  88. public final Environment getGlobalEnvironment() { return env; }
  89. public Expression parse (Object input)
  90. {
  91. return rewrite(input);
  92. }
  93. public final Expression rewrite_car (Pair pair, SyntaxForm syntax)
  94. {
  95. return rewrite_car(pair, syntax == null ? current_scope : syntax.getScope());
  96. }
  97. public final Expression rewrite_car (Pair pair, ScopeExp templateScope)
  98. {
  99. if (templateScope == current_scope
  100. || pair.getCar() instanceof SyntaxForm)
  101. return rewrite_car(pair, false);
  102. ScopeExp save_scope = setPushCurrentScope(templateScope);
  103. try
  104. {
  105. return rewrite_car(pair, false);
  106. }
  107. finally
  108. {
  109. setPopCurrentScope(save_scope);
  110. }
  111. }
  112. public final Expression rewrite_car (Pair pair, boolean function)
  113. {
  114. Object car = pair.getCar();
  115. if (pair instanceof PairWithPosition)
  116. return rewrite_with_position (car, function, (PairWithPosition) pair);
  117. else
  118. return rewrite (car, function);
  119. }
  120. /** Similar to rewrite_car.
  121. * However, we check for (quasiquote exp) specially, and handle that
  122. * directly. This is in case quasiquote isn't in scope.
  123. */
  124. public final Expression rewrite_car_for_lookup(Pair pair) {
  125. Object car = pair.getCar();
  126. if (car instanceof Pair) {
  127. Pair pcar = (Pair) car;
  128. if (pcar.getCar() == LispLanguage.quasiquote_sym) {
  129. Object pos = pushPositionOf(pair);
  130. Expression ret = Quote.quasiQuote.rewrite(pcar.getCdr(), this);
  131. popPositionOf(pos);
  132. return ret;
  133. }
  134. }
  135. return rewrite_car(pair, false);
  136. }
  137. Syntax currentSyntax;
  138. public Syntax getCurrentSyntax() { return currentSyntax; }
  139. /** The module instance containing the current macro.
  140. * This is only used temporarily, set when resolving a Declaration
  141. * bound to a macro, and used to set the macroContext field of the
  142. * TemplateScope created when expanding the macro's template(s). */
  143. Declaration macroContext;
  144. /**
  145. * Apply a Syntax object.
  146. * @param syntax the Syntax object whose rewrite method we call
  147. * @param form the syntax form (including the macro name)
  148. * @return the re-written form as an Expression object
  149. */
  150. Expression apply_rewrite (Syntax syntax, Pair form)
  151. {
  152. Expression exp = errorExp;
  153. Syntax saveSyntax = currentSyntax;
  154. currentSyntax = syntax;
  155. try
  156. {
  157. exp = syntax.rewriteForm(form, this);
  158. }
  159. finally
  160. {
  161. currentSyntax = saveSyntax;
  162. }
  163. return exp;
  164. }
  165. /** Check if declaraton is an alias for some other name.
  166. * This is needed to chase identifiers renamed for hygienic macro
  167. * expansion - see SyntaxRules.expand. */
  168. static ReferenceExp getOriginalRef(Declaration decl)
  169. {
  170. if (decl != null && decl.isAlias() && ! decl.isIndirectBinding())
  171. {
  172. Expression value = decl.getValue();
  173. if (value instanceof ReferenceExp)
  174. return (ReferenceExp) value;
  175. }
  176. return null;
  177. }
  178. public final boolean keywordsAreSelfEvaluating() {
  179. return ((LispLanguage) getLanguage()).keywordsAreSelfEvaluating();
  180. }
  181. public final boolean selfEvaluatingSymbol (Object obj)
  182. {
  183. return ((LispLanguage) getLanguage()).selfEvaluatingSymbol(obj);
  184. }
  185. /** True iff a form matches a literal symbol. */
  186. public final boolean matches(Object form, String literal)
  187. {
  188. return matches(form, null, literal);
  189. }
  190. public boolean matches(Object form, SyntaxForm syntax, String literal)
  191. {
  192. if (syntax != null)
  193. {
  194. // FIXME
  195. }
  196. if (form instanceof SyntaxForm)
  197. {
  198. // FIXME
  199. form = ((SyntaxForm) form).getDatum();
  200. }
  201. if (form instanceof SimpleSymbol && ! selfEvaluatingSymbol(form))
  202. {
  203. ReferenceExp rexp = getOriginalRef(lexical.lookup(form, -1));
  204. if (rexp != null)
  205. form = rexp.getSymbol();
  206. }
  207. return form instanceof SimpleSymbol
  208. && ((Symbol) form).getLocalPart() == literal;
  209. }
  210. public boolean matches(Object form, SyntaxForm syntax, Symbol literal)
  211. {
  212. if (syntax != null)
  213. {
  214. // FIXME
  215. }
  216. if (form instanceof SyntaxForm)
  217. {
  218. // FIXME
  219. form = ((SyntaxForm) form).getDatum();
  220. }
  221. if (form instanceof SimpleSymbol && ! selfEvaluatingSymbol(form))
  222. {
  223. ReferenceExp rexp = getOriginalRef(lexical.lookup(form, -1));
  224. if (rexp != null)
  225. form = rexp.getSymbol();
  226. }
  227. return form == literal;
  228. }
  229. public Object matchQuoted (Pair pair)
  230. {
  231. if (matches(pair.getCar(), LispLanguage.quote_str)
  232. && pair.getCdr() instanceof Pair
  233. && (pair = (Pair) pair.getCdr()).getCdr() == LList.Empty)
  234. return pair.getCar();
  235. return null;
  236. }
  237. public Declaration lookup(Object name, int namespace)
  238. {
  239. Declaration decl = lexical.lookup(name, namespace);
  240. if (decl != null && getLanguage().hasNamespace(decl, namespace))
  241. return decl;
  242. return currentModule().lookup(name, getLanguage(), namespace);
  243. }
  244. /** Find global Declaration, creating one if not found. */
  245. public Declaration lookupGlobal(Object name)
  246. {
  247. return lookupGlobal(name, -1);
  248. }
  249. /** Find global Declaration, creating one if not found. */
  250. public Declaration lookupGlobal(Object name, int namespace)
  251. {
  252. ModuleExp module = currentModule();
  253. Declaration decl = module.lookup(name, getLanguage(), namespace);
  254. if (decl == null)
  255. {
  256. decl = module.getNoDefine(name);
  257. decl.setIndirectBinding(true);
  258. }
  259. return decl;
  260. }
  261. /** Check if a Declaration is bound to a Syntax.
  262. * @param decl the Declaration to check
  263. * @return the Syntax bound to decl, or null.
  264. * In the former case, macroContext may be set as a side effect.
  265. */
  266. Syntax check_if_Syntax (Declaration decl)
  267. {
  268. Declaration d = Declaration.followAliases(decl);
  269. Object obj = null;
  270. Expression dval = d.getValue();
  271. if (dval != null && d.getFlag(Declaration.IS_SYNTAX))
  272. {
  273. try
  274. {
  275. if (decl.getValue() instanceof ReferenceExp)
  276. {
  277. Declaration context
  278. = ((ReferenceExp) decl.getValue()).contextDecl();
  279. if (context != null)
  280. macroContext = context;
  281. else if (current_scope instanceof TemplateScope)
  282. macroContext = ((TemplateScope) current_scope).macroContext;
  283. }
  284. else if (current_scope instanceof TemplateScope)
  285. macroContext = ((TemplateScope) current_scope).macroContext;
  286. obj = dval.eval(env);
  287. }
  288. catch (Error ex)
  289. {
  290. ex.printStackTrace();
  291. throw ex;
  292. }
  293. catch (Throwable ex)
  294. {
  295. ex.printStackTrace();
  296. error('e', "unable to evaluate macro for "+decl.getSymbol());
  297. }
  298. }
  299. else if (decl.getFlag(Declaration.IS_SYNTAX) && ! decl.needsContext())
  300. {
  301. StaticFieldLocation loc = StaticFieldLocation.make(decl);
  302. obj = loc.get(null);
  303. }
  304. return obj instanceof Syntax ? (Syntax) obj : null;
  305. }
  306. public Expression rewrite_pair (Pair p, boolean function)
  307. {
  308. Object p_car = p.getCar();
  309. Expression func;
  310. boolean useHelper = true;
  311. if (p_car instanceof Pair
  312. && ((Pair) p_car).getCar() == LispLanguage.splice_sym) {
  313. func = gnu.kawa.reflect.MakeAnnotation.makeAnnotationMaker
  314. (rewrite_car((Pair) ((Pair) p_car).getCdr(), false));
  315. useHelper = false;
  316. }
  317. else
  318. func = rewrite_car (p, true);
  319. Object proc = null;
  320. if (func instanceof QuoteExp)
  321. {
  322. proc = func.valueIfConstant();
  323. if (proc instanceof Syntax)
  324. return apply_rewrite((Syntax) proc, p);
  325. }
  326. ReferenceExp ref = null;
  327. if (func instanceof ReferenceExp)
  328. {
  329. ref = (ReferenceExp) func;
  330. Declaration decl = ref.getBinding();
  331. if (decl == null)
  332. {
  333. Object sym = ref.getSymbol();
  334. Symbol symbol;
  335. String name;
  336. if (sym instanceof Symbol && ! selfEvaluatingSymbol(sym))
  337. {
  338. symbol = (Symbol) sym;
  339. name = symbol.getName();
  340. }
  341. else
  342. {
  343. name = sym.toString();
  344. symbol = env.getSymbol(name);
  345. }
  346. proc = env.get(symbol,
  347. getLanguage().hasSeparateFunctionNamespace()
  348. ? EnvironmentKey.FUNCTION
  349. : null,
  350. null);
  351. if (proc instanceof Syntax)
  352. return apply_rewrite ((Syntax) proc, p);
  353. if (proc instanceof AutoloadProcedure)
  354. {
  355. try
  356. {
  357. proc = ((AutoloadProcedure) proc).getLoaded();
  358. }
  359. catch (RuntimeException ex)
  360. {
  361. proc = null;
  362. }
  363. }
  364. }
  365. else
  366. {
  367. Declaration saveContext = macroContext;
  368. Syntax syntax = check_if_Syntax (decl);
  369. if (syntax != null)
  370. {
  371. Expression e = apply_rewrite (syntax, p);
  372. macroContext = saveContext;
  373. return e;
  374. }
  375. }
  376. ref.setProcedureName(true);
  377. if (getLanguage().hasSeparateFunctionNamespace())
  378. func.setFlag(ReferenceExp.PREFER_BINDING2);
  379. }
  380. boolean isNamedPartDecl = func instanceof ReferenceExp
  381. && (((ReferenceExp) func).getBinding()==getNamedPartDecl);
  382. if (isNamedPartDecl)
  383. useHelper = false;
  384. Object cdr = p.getCdr();
  385. int cdr_length = listLength(cdr);
  386. if (cdr_length < 0)
  387. return syntaxError
  388. ("improper list (circular or dotted) is not allowed here");
  389. Expression applyFunction = useHelper ? applyFunction(func) : null;
  390. Stack vec = new Stack();
  391. if (applyFunction != null) {
  392. vec.add(func);
  393. func = applyFunction;
  394. }
  395. ScopeExp save_scope = current_scope;
  396. int first_keyword = -1;
  397. int last_keyword = -1;
  398. boolean bad_keyword_reported = false;
  399. int firstSpliceArg = -1;
  400. int i = 0;
  401. while (cdr != LList.Empty)
  402. {
  403. if (cdr instanceof SyntaxForm)
  404. {
  405. SyntaxForm sf = (SyntaxForm) cdr;
  406. cdr = sf.getDatum();
  407. // I.e. first time do equivalent of setPushCurrentScope
  408. if (current_scope == save_scope)
  409. lexical.pushSaveTopLevelRedefs();
  410. setCurrentScope(sf.getScope());
  411. }
  412. Object save_pos = pushPositionOf(cdr);
  413. Pair cdr_pair = (Pair) cdr;
  414. Object cdr_car = cdr_pair.getCar();
  415. Object cdr_cdr = cdr_pair.getCdr();
  416. Expression arg;
  417. if (cdr_car instanceof Keyword) {
  418. if (first_keyword < 0) {
  419. first_keyword = i;
  420. last_keyword = i - 2; // To suppress incorrect warnings
  421. }
  422. if (bad_keyword_reported)
  423. ;
  424. else if (keywordsAreSelfEvaluating())
  425. last_keyword = i;
  426. else if (i == last_keyword + 1 || i + 1 == cdr_length) {
  427. bad_keyword_reported = true;
  428. error('w', "missing value after unquoted keyword");
  429. } else if (i != last_keyword + 2) {
  430. bad_keyword_reported = true;
  431. error('w', "keyword separated from other keyword arguments");
  432. } else
  433. last_keyword = i;
  434. arg = QuoteExp.getInstance(cdr_car, this);
  435. arg.setFlag(QuoteExp.IS_KEYWORD);
  436. } else if (cdr_cdr instanceof Pair
  437. // FIXME should check binding for ... is builtin ...
  438. && ((Pair) cdr_cdr).getCar() == LispLanguage.dots3_sym) {
  439. LambdaExp dotsLambda = new LambdaExp();
  440. pushScanContext(dotsLambda);
  441. dotsLambda.body = rewrite_car(cdr_pair, false);
  442. ScanContext scanContext = getScanContext();
  443. LinkedHashMap<Declaration,Declaration> sdecls
  444. = scanContext.decls;
  445. int nseqs = sdecls.size();
  446. ArrayList<Expression> scanExps = scanContext.scanExpressions;
  447. int nexps = scanExps == null ? 0 : scanExps.size();
  448. Expression[] subargs = new Expression[nseqs + nexps + 1];
  449. subargs[0] = dotsLambda;
  450. popScanContext();
  451. Iterator<Declaration> sit = sdecls.keySet().iterator();
  452. int j = 1;
  453. while (sit.hasNext()) {
  454. Declaration sdecl = sit.next();
  455. if (curScanNesting() > 0) {
  456. sdecl = getScanContext().addSeqDecl(sdecl);
  457. }
  458. ReferenceExp rexp = new ReferenceExp(sdecl);
  459. subargs[j++] = rexp;
  460. }
  461. for (int k = 0; k < nexps; k++) {
  462. subargs[j++] = scanExps.get(k);
  463. }
  464. arg = new ApplyExp(Scheme.map, subargs);
  465. arg = new ApplyExp(MakeSplice.quoteInstance, arg);
  466. cdr_cdr = ((Pair) cdr_cdr).getCdr();
  467. if (firstSpliceArg < 0)
  468. firstSpliceArg = i + (applyFunction != null ? 1 : 0);
  469. } else {
  470. Object cdr_car_car;
  471. if (cdr_car instanceof Pair
  472. && ((cdr_car_car = ((Pair) cdr_car).getCar()) == LispLanguage.splice_sym
  473. || cdr_car_car == LispLanguage.splice_colon_sym)) {
  474. arg = rewrite_car((Pair) ((Pair) cdr_car).getCdr(), false);
  475. QuoteExp splicer = cdr_car_car == LispLanguage.splice_sym
  476. ? MakeSplice.quoteInstance
  477. : MakeSplice.quoteKeywordsAllowedInstance;
  478. arg = new ApplyExp(splicer, arg);
  479. if (firstSpliceArg < 0)
  480. firstSpliceArg = i + (applyFunction != null ? 1 : 0);
  481. }
  482. else
  483. arg = rewrite_car (cdr_pair, false);
  484. }
  485. i++;
  486. vec.addElement(arg);
  487. cdr = cdr_cdr;
  488. popPositionOf(save_pos);
  489. }
  490. Expression[] args = new Expression[vec.size()];
  491. vec.copyInto(args);
  492. if (save_scope != current_scope)
  493. setPopCurrentScope(save_scope);
  494. if (isNamedPartDecl)
  495. return rewrite_lookup(args[0], args[1], function);
  496. ApplyExp app = new ApplyExp(func, args);
  497. app.firstSpliceArg = firstSpliceArg;
  498. if (first_keyword >= 0)
  499. {
  500. app.numKeywordArgs = (last_keyword - first_keyword) / 2 + 1;
  501. app.firstKeywordArgIndex = first_keyword + (applyFunction != null ? 2 : 1);
  502. }
  503. return app;
  504. }
  505. public Expression rewrite_lookup(Expression part1, Expression part2, boolean function) {
  506. Symbol sym = namespaceResolve(part1, part2);
  507. if (sym != null)
  508. return rewrite(sym, function);
  509. // FIXME don't copy the args array in makeExp ...
  510. return CompileNamedPart.makeExp(part1, part2);
  511. }
  512. public Namespace namespaceResolvePrefix (Expression context)
  513. {
  514. if (context instanceof ReferenceExp)
  515. {
  516. ReferenceExp rexp = (ReferenceExp) context;
  517. Declaration decl = rexp.getBinding();
  518. Object val;
  519. if (decl == null || decl.getFlag(Declaration.IS_UNKNOWN))
  520. {
  521. Object rsym = rexp.getSymbol();
  522. Symbol sym = rsym instanceof Symbol ? (Symbol) rsym
  523. : env.getSymbol(rsym.toString());
  524. val = env.get(sym, null);
  525. }
  526. else if (decl.isNamespaceDecl())
  527. {
  528. val = decl.getConstantValue();
  529. }
  530. else
  531. val = null;
  532. if (val instanceof Namespace)
  533. {
  534. Namespace ns = (Namespace) val;
  535. String uri = ns.getName();
  536. if (uri != null && uri.startsWith("class:"))
  537. return null;
  538. return ns;
  539. }
  540. }
  541. return null;
  542. }
  543. public Symbol namespaceResolve (Namespace ns, Expression member)
  544. {
  545. if (ns != null && member instanceof QuoteExp)
  546. {
  547. String mem = ((QuoteExp) member).getValue().toString().intern();
  548. return ns.getSymbol(mem);
  549. }
  550. return null;
  551. }
  552. public Symbol namespaceResolve (Expression context, Expression member)
  553. {
  554. return namespaceResolve(namespaceResolvePrefix(context), member);
  555. }
  556. public static Object stripSyntax (Object obj)
  557. {
  558. while (obj instanceof SyntaxForm)
  559. obj = ((SyntaxForm) obj).getDatum();
  560. return obj;
  561. }
  562. public static Object safeCar (Object obj)
  563. {
  564. while (obj instanceof SyntaxForm)
  565. obj = ((SyntaxForm) obj).getDatum();
  566. if (! (obj instanceof Pair))
  567. return null;
  568. return stripSyntax(((Pair) obj).getCar());
  569. }
  570. public static Object safeCdr (Object obj)
  571. {
  572. while (obj instanceof SyntaxForm)
  573. obj = ((SyntaxForm) obj).getDatum();
  574. if (! (obj instanceof Pair))
  575. return null;
  576. return stripSyntax(((Pair) obj).getCdr());
  577. }
  578. /** Returns the length of a syntax list.
  579. * Returns Integer.MIN_VALUE for cyclic lists.
  580. * For impure lists returns the negative of one more than
  581. * the number of pairs before the "dot".
  582. * Similar to LList.listLength, but handles SyntaxForm more efficiently. */
  583. public static int listLength(Object obj)
  584. {
  585. // Based on list-length implementation in
  586. // Guy L Steele jr: "Common Lisp: The Language", 2nd edition, page 414
  587. int n = 0;
  588. Object slow = obj;
  589. Object fast = obj;
  590. for (;;)
  591. {
  592. // 'n' is number of previous Pairs before 'fast' cursor.
  593. while (fast instanceof SyntaxForm)
  594. fast = ((SyntaxForm) fast).getDatum();
  595. while (slow instanceof SyntaxForm)
  596. slow = ((SyntaxForm) slow).getDatum();
  597. if (fast == LList.Empty)
  598. return n;
  599. if (! (fast instanceof Pair))
  600. return -1-n;
  601. n++;
  602. Object next = ((Pair) fast).getCdr();
  603. while (next instanceof SyntaxForm)
  604. next = ((SyntaxForm) next).getDatum();
  605. if (next == LList.Empty)
  606. return n;
  607. if (! (next instanceof Pair))
  608. return -1-n;
  609. slow = ((Pair)slow).getCdr();
  610. fast = ((Pair)next).getCdr();
  611. n++;
  612. if (fast == slow)
  613. return Integer.MIN_VALUE;
  614. }
  615. }
  616. public void rewriteInBody (Object exp)
  617. {
  618. if (exp instanceof SyntaxForm)
  619. {
  620. SyntaxForm sf = (SyntaxForm) exp;
  621. ScopeExp save_scope = setPushCurrentScope(sf.getScope());
  622. try
  623. {
  624. rewriteInBody(sf.getDatum());
  625. }
  626. finally
  627. {
  628. setPopCurrentScope(save_scope);
  629. }
  630. }
  631. else if (exp instanceof ValuesFromLList)
  632. {
  633. // Optimization of following case.
  634. // More importantly, we make use of the line number information.
  635. for (Object vs = ((ValuesFromLList) exp).values;
  636. vs != LList.Empty; )
  637. {
  638. Pair p = (Pair) vs;
  639. pushForm(rewrite_car(p, false));
  640. vs = p.getCdr();
  641. }
  642. }
  643. else if (exp instanceof Values)
  644. {
  645. Object[] vals = ((Values) exp).getValues();
  646. for (int i = 0; i < vals.length; i++)
  647. rewriteInBody(vals[i]);
  648. }
  649. else {
  650. Expression e = rewrite(exp, false);
  651. setLineOf(e);
  652. pushForm(e);
  653. }
  654. }
  655. public int getCompletions(Environment env,
  656. String nameStart, Object property,
  657. String namespaceUri,
  658. List<? super String> matches) {
  659. LocationEnumeration e = env.enumerateAllLocations();
  660. int count = 0;
  661. while (e.hasMoreElements()) {
  662. Location loc = e.nextLocation();
  663. Symbol sym = loc.getKeySymbol();
  664. String local = sym == null ? null : sym.getLocalPart();
  665. if (local != null && local.startsWith(nameStart)
  666. && property == loc.getKeyProperty()
  667. && namespaceUri == sym.getNamespaceURI()) {
  668. count++;
  669. matches.add(local);
  670. }
  671. }
  672. return count;
  673. }
  674. public Object namespaceResolve(Object name) {
  675. Object prefix = null;
  676. Expression part2 = null;
  677. Pair p;
  678. if (name instanceof Pair
  679. && safeCar(p = (Pair) name) == LispLanguage.lookup_sym
  680. && p.getCdr() instanceof Pair
  681. && (p = (Pair) p.getCdr()).getCdr() instanceof Pair) {
  682. prefix = namespaceResolve(p.getCar());
  683. if (! (stripSyntax(prefix) instanceof Symbol))
  684. return name;
  685. part2 = rewrite_car_for_lookup((Pair) p.getCdr());
  686. }
  687. else if (name instanceof Symbol) {
  688. Symbol s = (Symbol) name;
  689. if (s.hasUnknownNamespace()) {
  690. String loc = s.getLocalPart();
  691. prefix = Symbol.valueOf(s.getPrefix());
  692. part2 = QuoteExp.getInstance(Symbol.valueOf(s.getLocalPart()));
  693. }
  694. }
  695. if (part2 != null) {
  696. Expression part1 = rewrite(prefix);
  697. Symbol sym = namespaceResolve(part1, part2);
  698. if (sym != null)
  699. return sym;
  700. String combinedName = CompileNamedPart.combineName(part1, part2);
  701. if (combinedName != null)
  702. return Namespace.EmptyNamespace.getSymbol(combinedName);
  703. }
  704. return name;
  705. }
  706. /**
  707. * Re-write a Scheme expression in S-expression format into internal form.
  708. */
  709. public Expression rewrite(Object exp) {
  710. return rewrite(exp, 'N');
  711. }
  712. /**
  713. * Re-write a Scheme expression in S-expression format into internal form.
  714. */
  715. public Expression rewrite(Object exp, boolean function) {
  716. return rewrite(exp, function ? 'F' : 'N');
  717. }
  718. /** Re-write a Scheme expression in S-expression format into internal form.
  719. * @param mode either 'N' (normal), 'F' (function application context),
  720. * or 'M' (macro-checking).
  721. */
  722. public Expression rewrite(Object exp, char mode) {
  723. if (exp instanceof SyntaxForm) {
  724. SyntaxForm sf = (SyntaxForm) exp;
  725. ScopeExp save_scope = setPushCurrentScope(sf.getScope());
  726. try {
  727. Expression s = rewrite(sf.getDatum(), mode);
  728. return s;
  729. } finally {
  730. setPopCurrentScope(save_scope);
  731. }
  732. }
  733. boolean function = mode != 'N';
  734. if (exp instanceof Pair) {
  735. Expression e = rewrite_pair((Pair) exp, function);
  736. setLineOf(e);
  737. return e;
  738. } else if (exp instanceof Symbol && ! selfEvaluatingSymbol(exp)) {
  739. Symbol s = (Symbol) exp;
  740. // Check if we're handling a completion request.
  741. int complete = s.getLocalName()
  742. .indexOf(CommandCompleter.COMPLETE_REQUEST);
  743. boolean separate = getLanguage().hasSeparateFunctionNamespace();
  744. if (complete >= 0) {
  745. List<String> candidates = new ArrayList<String>();
  746. String prefix = s.toString().substring(0, complete);
  747. Object property = function && separate ? EnvironmentKey.FUNCTION
  748. : null;
  749. int symspace = function ? Language.FUNCTION_NAMESPACE
  750. : Language.VALUE_NAMESPACE;
  751. getCompletions(env, prefix, property, s.getNamespaceURI(),
  752. candidates);
  753. lexical.getCompletingSymbols(prefix, symspace,
  754. candidates);
  755. throw new CommandCompleter(complete, candidates,
  756. prefix, prefix.length(), this);
  757. }
  758. if (s.hasUnknownNamespace()) {
  759. String loc = s.getLocalPart();
  760. return rewrite_lookup(rewrite(Symbol.valueOf(s.getPrefix()), false),
  761. QuoteExp.getInstance(Symbol.valueOf(s.getLocalPart())),
  762. function);
  763. }
  764. Declaration decl = lexical.lookup(exp, function);
  765. Declaration cdecl = null;
  766. // If we're nested inside a class (in a ClassExp) then the field
  767. // and methods names of this class and super-classes/interfaces
  768. // need to be searched.
  769. ScopeExp scope = current_scope;
  770. int decl_nesting = decl == null ? -1 : ScopeExp.nesting(decl.context);
  771. String dname;
  772. if (exp instanceof SimpleSymbol)
  773. dname = exp.toString();
  774. else {
  775. dname = null;
  776. scope = null;
  777. }
  778. for (;scope != null; scope = scope.getOuter()) {
  779. if (scope instanceof LambdaExp
  780. && scope.getOuter() instanceof ClassExp // redundant? FIXME
  781. && ((LambdaExp) scope).isClassMethod()
  782. && mode != 'M') {
  783. if (decl_nesting >= ScopeExp.nesting(scope.getOuter()))
  784. break;
  785. LambdaExp caller = (LambdaExp) scope;
  786. ClassExp cexp = (ClassExp) scope.getOuter();
  787. ClassType ctype = (ClassType) cexp.getClassType();
  788. // If ctype is a class that hasn't been compiled yet (and
  789. // ClassExp#declareParts hasn't been called yet)
  790. // then we may may get a tentative Field created
  791. // by ClassExp#createFields.
  792. // BUG: This doesn't work for not-yet compiled methods.
  793. Member part = SlotGet.lookupMember(ctype, dname, ctype);
  794. boolean contextStatic
  795. = (caller == cexp.clinitMethod
  796. || (caller != cexp.initMethod
  797. && caller.nameDecl.isStatic()));
  798. if (part == null) {
  799. PrimProcedure[] methods
  800. = ClassMethods.getMethods(ctype, dname,
  801. contextStatic ? 'S' : 'V',
  802. ctype, language);
  803. if (methods.length == 0)
  804. continue;
  805. } else if (decl != null && ! dname.equals(part.getName())) {
  806. continue;
  807. }
  808. Expression part1;
  809. // FIXME We're throwing away 'part', which is wasteful.
  810. if (contextStatic)
  811. part1 = new ReferenceExp(((ClassExp) caller.getOuter()).nameDecl);
  812. else
  813. part1 = new ThisExp(caller.firstDecl());
  814. return CompileNamedPart.makeExp(part1,
  815. QuoteExp.getInstance(dname));
  816. }
  817. }
  818. Object nameToLookup;
  819. if (decl != null) {
  820. nameToLookup = decl.getSymbol();
  821. exp = null;
  822. ReferenceExp rexp = getOriginalRef(decl);
  823. if (rexp != null) {
  824. decl = rexp.getBinding();
  825. if (decl == null) {
  826. exp = rexp.getSymbol();
  827. nameToLookup = exp;
  828. }
  829. }
  830. } else {
  831. nameToLookup = exp;
  832. }
  833. Symbol symbol = (Symbol) exp;
  834. if (decl != null) {
  835. if (current_scope instanceof TemplateScope && decl.needsContext())
  836. cdecl = ((TemplateScope) current_scope).macroContext;
  837. else if (decl.getFlag(Declaration.FIELD_OR_METHOD)
  838. && ! decl.isStatic()) {
  839. scope = currentScope();
  840. for (;;) {
  841. if (scope == null)
  842. throw new Error("internal error: missing "+decl);
  843. if (scope.getOuter() == decl.context) // I.e. same class.
  844. break;
  845. scope = scope.getOuter();
  846. }
  847. cdecl = scope.firstDecl();
  848. }
  849. } else {
  850. Location loc
  851. = env.lookup(symbol,
  852. function && separate ? EnvironmentKey.FUNCTION
  853. : null);
  854. if (loc != null)
  855. loc = loc.getBase();
  856. if (loc instanceof FieldLocation) {
  857. FieldLocation floc = (FieldLocation) loc;
  858. try {
  859. decl = floc.getDeclaration();
  860. if (! inlineOk(null)
  861. // A kludge - we get a bunch of testsuite failures
  862. // if we don't inline $lookup$. FIXME.
  863. && (decl != getNamedPartDecl
  864. // Another kludge to support "object" as a
  865. // type specifier.
  866. && ! isObjectSyntax(floc.getDeclaringClass(),
  867. floc.getMemberName())))
  868. decl = null;
  869. else if (immediate) {
  870. if (! decl.isStatic()) {
  871. cdecl = new Declaration("(module-instance)");
  872. cdecl.setValue(new QuoteExp(floc.getInstance()));
  873. }
  874. } else if (decl.isStatic()) {
  875. // If the class has been loaded through ZipLoader
  876. // or ArrayClassLoader then it might not be visible
  877. // if loaded through some other ClassLoader.
  878. Class fclass = floc.getRClass();
  879. ClassLoader floader;
  880. if (fclass == null
  881. || ((floader = fclass.getClassLoader())
  882. instanceof ZipLoader)
  883. || floader instanceof ArrayClassLoader)
  884. decl = null;
  885. } else
  886. decl = null;
  887. } catch (Exception ex) {
  888. error('e',
  889. "exception loading '" + exp
  890. + "' - " + ex.getMessage());
  891. decl = null;
  892. }
  893. }
  894. else if (mode != 'M' && (loc == null || ! loc.isBound()))
  895. {
  896. Expression e = checkDefaultBinding(symbol, this);
  897. if (e != null)
  898. return e;
  899. }
  900. /*
  901. else if (Compilation.inlineOk && function) {
  902. // Questionable. fail with new set_b implementation,
  903. // which just call rewrite_car on the lhs,
  904. // if we don't require function to be true. FIXME.
  905. decl = Declaration.getDeclaration(proc);
  906. }
  907. */
  908. }
  909. if (decl != null) {
  910. // A special kludge to deal with the overloading between the
  911. // object macro and object as being equivalent to java.lang.Object.
  912. // A cleaner solution would be to use an identifier macro.
  913. Field dfield = decl.getField();
  914. if (! function && dfield != null
  915. && isObjectSyntax(dfield.getDeclaringClass(),
  916. dfield.getName()))
  917. return QuoteExp.getInstance(Object.class);
  918. if (decl.getContext() instanceof PatternScope)
  919. return syntaxError("reference to pattern variable "+decl.getName()+" outside syntax template");
  920. }
  921. if (decl == null && function
  922. && nameToLookup==LispLanguage.lookup_sym)
  923. decl = getNamedPartDecl;
  924. int scanNesting = decl == null ? 0
  925. : Declaration.followAliases(decl).getScanNesting();
  926. if (scanNesting > 0) {
  927. if (scanNesting > curScanNesting())
  928. error('e', "using repeat variable '"+decl.getName()+"' while not in repeat context");
  929. else {
  930. return new ReferenceExp
  931. (scanContextStack.get(scanNesting-1).addSeqDecl(decl));
  932. }
  933. }
  934. ReferenceExp rexp = new ReferenceExp (nameToLookup, decl);
  935. rexp.setContextDecl(cdecl);
  936. rexp.setLine(this);
  937. if (function && separate)
  938. rexp.setFlag(ReferenceExp.PREFER_BINDING2);
  939. return rexp;
  940. } else if (exp instanceof LangExp)
  941. return rewrite(((LangExp) exp).getLangValue(), function);
  942. else if (exp instanceof Expression)
  943. return (Expression) exp;
  944. else if (exp == Special.abstractSpecial)
  945. return QuoteExp.abstractExp;
  946. else if (exp == Boolean.TRUE)
  947. return QuoteExp.trueExp;
  948. else if (exp == Boolean.FALSE)
  949. return QuoteExp.falseExp;
  950. else if (exp == Special.nativeSpecial)
  951. return QuoteExp.nativeExp;
  952. else {
  953. if (exp instanceof Keyword && ! keywordsAreSelfEvaluating())
  954. error('w', "keyword should be quoted if not in argument position");
  955. if (exp instanceof String)
  956. exp = new IString((String) exp);
  957. return QuoteExp.getInstance(Quote.quote(exp, this), this);
  958. }
  959. }
  960. /**
  961. * If a symbol is lexically unbound, look for a default binding.
  962. * The default implementation does the following:
  963. *
  964. * If the symbol is the name of an existing Java class, return that class.
  965. * Handles both with and without (semi-deprecated) angle-brackets:
  966. * {@code <java.lang.Integer>} and {@code java.lang.Integer}.
  967. * Also handles arrays, such as {@code java.lang.String[]}.
  968. *
  969. * If the symbol starts with {@code '@'} parse as an annotation class.
  970. *
  971. * Recognizes quanties with units, such as {@code 2m} and {@code 3m/s^2}.
  972. *
  973. * Handles the xml and unit namespaces.
  974. *
  975. * @return null if no binding, otherwise an Expression.
  976. *
  977. * FIXME: This method should be refactored. The quantities parsing should
  978. * be moved to its own method at least.
  979. */
  980. public Expression checkDefaultBinding(Symbol symbol, Translator tr) {
  981. Namespace namespace = symbol.getNamespace();
  982. String local = symbol.getLocalPart();
  983. String name = symbol.toString();
  984. int len = name.length();
  985. if (namespace instanceof XmlNamespace)
  986. return makeQuoteExp(((XmlNamespace) namespace).get(local));
  987. String namespaceName = namespace.getName();
  988. if (namespaceName == LispLanguage.unitNamespace.getName()) {
  989. Object val = Unit.lookup(local);
  990. if (val != null)
  991. return makeQuoteExp(val);
  992. }
  993. if (namespaceName == LispLanguage.entityNamespace.getName()) {
  994. Object val = lookupStandardEntity(local);
  995. if (val == null) {
  996. tr.error('e', "unknown entity name "+local);
  997. val = "{"+namespace.getPrefix()+":"+local+"}";
  998. }
  999. return makeQuoteExp(val);
  1000. }
  1001. char ch0 = name.charAt(0);
  1002. if (ch0 == '@') { // Deprecated - reader now returns ($splice$ ATYPE).
  1003. String rest = name.substring(1);
  1004. Expression classRef = tr.rewrite(Symbol.valueOf(rest));
  1005. return MakeAnnotation.makeAnnotationMaker(classRef);
  1006. }
  1007. // Look for quantities.
  1008. if (ch0 == '-' || ch0 == '+' || Character.digit(ch0, 10) >= 0) {
  1009. // 1: initial + or -1 seen.
  1010. // 2: digits seen
  1011. // 3: '.' seen
  1012. // 4: fraction seen
  1013. // 5: [eE][=+]?[0-9]+ seen
  1014. int state = 0;
  1015. int i = 0;
  1016. for (; i < len; i++) {
  1017. char ch = name.charAt(i);
  1018. if (Character.digit(ch, 10) >= 0)
  1019. state = state < 3 ? 2 : state < 5 ? 4 : 5;
  1020. else if ((ch == '+' || ch == '-') && state == 0)
  1021. state = 1;
  1022. else if (ch == '.' && state < 3)
  1023. state = 3;
  1024. else if ((ch == 'e' || ch == 'E') && (state == 2 || state == 4)
  1025. && i + 1 < len) {
  1026. int j = i + 1;
  1027. char next = name.charAt(j);
  1028. if ((next == '-' || next == '+') && ++j < len)
  1029. next = name.charAt(j);
  1030. if (Character.digit(next, 10) < 0)
  1031. break;
  1032. state = 5;
  1033. i = j + 1;
  1034. }
  1035. else
  1036. break;
  1037. }
  1038. tryQuantity:
  1039. if (i < len && state > 1) {
  1040. DFloNum num = new DFloNum(name.substring(0, i));
  1041. boolean div = false;
  1042. ArrayList vec = new ArrayList();
  1043. for (; i < len;) {
  1044. char ch = name.charAt(i++);
  1045. if (ch == '*') {
  1046. if (i == len)
  1047. break tryQuantity;
  1048. ch = name.charAt(i++);
  1049. } else if (ch == '/') {
  1050. if (i == len || div)
  1051. break tryQuantity;
  1052. div = true;
  1053. ch = name.charAt(i++);
  1054. }
  1055. int unitStart = i - 1;
  1056. int unitEnd;
  1057. for (;;) {
  1058. if (!Character.isLetter(ch)) {
  1059. unitEnd = i - 1;
  1060. if (unitEnd == unitStart)
  1061. break tryQuantity;
  1062. break;
  1063. }
  1064. if (i == len) {
  1065. unitEnd = i;
  1066. ch = '1';
  1067. break;
  1068. }
  1069. ch = name.charAt(i++);
  1070. }
  1071. vec.add(name.substring(unitStart, unitEnd));
  1072. boolean expRequired = false;
  1073. if (ch == '^') {
  1074. expRequired = true;
  1075. if (i == len)
  1076. break tryQuantity;
  1077. ch = name.charAt(i++);
  1078. }
  1079. boolean neg = div;
  1080. if (ch == '+') {
  1081. expRequired = true;
  1082. if (i == len)
  1083. break tryQuantity;
  1084. ch = name.charAt(i++);
  1085. } else if (ch == '-') {
  1086. expRequired = true;
  1087. if (i == len)
  1088. break tryQuantity;
  1089. ch = name.charAt(i++);
  1090. neg = !neg;
  1091. }
  1092. int nexp = 0;
  1093. int exp = 0;
  1094. for (;;) {
  1095. int dig = Character.digit(ch, 10);
  1096. if (dig <= 0) {
  1097. i--;
  1098. break;
  1099. }
  1100. exp = 10 * exp + dig;
  1101. nexp++;
  1102. if (i == len)
  1103. break;
  1104. ch = name.charAt(i++);
  1105. }
  1106. if (nexp == 0) {
  1107. exp = 1;
  1108. if (expRequired)
  1109. break tryQuantity;
  1110. }
  1111. if (neg)
  1112. exp = -exp;
  1113. vec.add(IntNum.make(exp));
  1114. }
  1115. if (i == len) {
  1116. int nunits = vec.size() >> 1;
  1117. Expression[] units = new Expression[nunits];
  1118. for (i = 0; i < nunits; i++) {
  1119. String uname = (String) vec.get(2 * i);
  1120. Symbol usym = LispLanguage.unitNamespace.getSymbol(uname.intern());
  1121. Expression uref = tr.rewrite(usym);
  1122. IntNum uexp = (IntNum) vec.get(2 * i + 1);
  1123. if (uexp.longValue() != 1)
  1124. uref = new ApplyExp(Expt.expt,
  1125. new Expression[] {
  1126. uref, makeQuoteExp(uexp)
  1127. });
  1128. units[i] = uref;
  1129. }
  1130. Expression unit;
  1131. if (nunits == 1)
  1132. unit = units[0];
  1133. else
  1134. unit = new ApplyExp(MultiplyOp.TIMES, units);
  1135. return new ApplyExp(MultiplyOp.TIMES,
  1136. new Expression[] {
  1137. makeQuoteExp(num),
  1138. unit
  1139. });
  1140. }
  1141. }
  1142. }
  1143. boolean sawAngle;
  1144. if (len > 2 && ch0 == '<' && name.charAt(len - 1) == '>') {
  1145. name = name.substring(1, len - 1);
  1146. len -= 2;
  1147. sawAngle = true;
  1148. } else
  1149. sawAngle = false;
  1150. int rank = 0;
  1151. while (len > 2 && name.charAt(len - 2) == '['
  1152. && name.charAt(len - 1) == ']') {
  1153. len -= 2;
  1154. rank++;
  1155. }
  1156. //(future) String cname = (namespace == LispPackage.ClassNamespace) ? local : name;
  1157. String cname = name;
  1158. if (rank != 0)
  1159. cname = name.substring(0, len);
  1160. try {
  1161. Type type = getLanguage().getNamedType(cname);
  1162. if (rank > 0 && (!sawAngle || type == null)) {
  1163. Symbol tsymbol = namespace.getSymbol(cname.intern());
  1164. Expression texp = tr.rewrite(tsymbol, false);
  1165. texp = InlineCalls.inlineCalls(texp, tr);
  1166. if (!(texp instanceof ErrorExp))
  1167. type = tr.getLanguage().getTypeFor(texp);
  1168. }
  1169. if (type != null) {
  1170. // Somewhat inconsistent: Types named by getNamedType are Type,
  1171. // while standard type/classes are Class. FIXME.
  1172. while (--rank >= 0) {
  1173. type = gnu.bytecode.ArrayType.make(type);
  1174. }
  1175. return makeQuoteExp(type);
  1176. }
  1177. Class clas;
  1178. type = Type.lookupType(cname);
  1179. if (type instanceof gnu.bytecode.PrimType)
  1180. clas = type.getReflectClass();
  1181. else {
  1182. if (cname.indexOf('.') < 0)
  1183. cname = (tr.classPrefix
  1184. + Mangling.mangleNameIfNeeded(cname));
  1185. if (rank == 0) {
  1186. ModuleManager mmanager = ModuleManager.getInstance();
  1187. ModuleInfo typeInfo = mmanager.searchWithClassName(cname);
  1188. if (typeInfo != null) {
  1189. Compilation tcomp = typeInfo.getCompilation();
  1190. if (tcomp != null && tcomp.mainClass != null) {
  1191. QuoteExp qexp = new QuoteExp(tcomp.mainClass,
  1192. Type.javalangClassType);
  1193. qexp.setLocation(this);
  1194. return qexp;
  1195. }
  1196. }
  1197. }
  1198. clas = ClassType.getContextClass(cname);
  1199. }
  1200. if (clas != null) {
  1201. if (rank > 0) {
  1202. type = Type.make(clas);
  1203. while (--rank >= 0) {
  1204. type = gnu.bytecode.ArrayType.make(type);
  1205. }
  1206. clas = type.getReflectClass();
  1207. }
  1208. return makeQuoteExp(clas);
  1209. }
  1210. } catch (ClassNotFoundException ex) {
  1211. Package pack = gnu.bytecode.ArrayClassLoader.getContextPackage(name);
  1212. if (pack != null)
  1213. return makeQuoteExp(pack);
  1214. } catch (NoClassDefFoundError ex) {
  1215. tr.error('w', "error loading class " + cname + " - " + ex.getMessage() + " not found");
  1216. } catch (Exception ex) {
  1217. }
  1218. if (name.startsWith("array")) {
  1219. Type atype = LispLanguage.decodeArrayType(name);
  1220. if (atype != null)
  1221. return makeQuoteExp(atype);
  1222. }
  1223. return null;
  1224. }
  1225. static Map<String,String> standardEntities;
  1226. public static synchronized String lookupStandardEntity(String key) {
  1227. if (standardEntities == null) {
  1228. standardEntities = new HashMap<String,String>();
  1229. Char.addNamedChars(standardEntities);
  1230. }
  1231. String val = standardEntities.get(key);
  1232. if (val != null)
  1233. return val;
  1234. return val = StandardNamedChars.instance.get(key);
  1235. }
  1236. public static void setLine(Expression exp, Object location)
  1237. {
  1238. if (location instanceof SourceLocator)
  1239. exp.setLocation((SourceLocator) location);
  1240. }
  1241. public static void setLine(Declaration decl, Object location)
  1242. {
  1243. if (location instanceof SourceLocator)
  1244. decl.setLocation((SourceLocator) location);
  1245. }
  1246. PairWithPosition positionPair;
  1247. /*
  1248. public Object pushPositionOfCar(Object pair)
  1249. {
  1250. if (pair instanceof Pair)
  1251. {
  1252. Object car = ((Pair) pair).getCar();
  1253. if (car instanceof PairWithPosition)
  1254. pair = car;
  1255. }
  1256. return pushPositionOf(pair);
  1257. }*/
  1258. /** Note current line number position from a PairWithPosition.
  1259. * Return an object to pass to popPositionOf.
  1260. */
  1261. public Object pushPositionOf(Object pos)
  1262. {
  1263. if (pos instanceof SyntaxForm)
  1264. pos = ((SyntaxForm) pos).getDatum();
  1265. PairWithPosition pair;
  1266. if (pos instanceof PairWithPosition)
  1267. pair = (PairWithPosition) pos;
  1268. else if (pos instanceof SourceLocator)
  1269. pair = new PairWithPosition((SourceLocator) pos, null, null);
  1270. else
  1271. return null;
  1272. Object saved;
  1273. if (positionPair == null
  1274. || positionPair.getFileName() != getFileName()
  1275. || positionPair.getLineNumber() != getLineNumber()
  1276. || positionPair.getColumnNumber() != getColumnNumber())
  1277. {
  1278. saved = new PairWithPosition(this, this, positionPair);
  1279. }
  1280. else
  1281. saved = positionPair;
  1282. setLine(pos);
  1283. positionPair = pair;
  1284. return saved;
  1285. }
  1286. /** Restore line number position from a previous pushPositionOf.
  1287. * @param saved value returned by matching pushPositionOf.
  1288. */
  1289. public void popPositionOf(Object saved)
  1290. {
  1291. if (saved == null)
  1292. return;
  1293. setLine(saved);
  1294. positionPair = (PairWithPosition) saved;
  1295. if (positionPair.getCar() == this)
  1296. positionPair = (PairWithPosition) positionPair.getCdr();
  1297. }
  1298. public void errorWithPosition(String message, Object form) {
  1299. Object save = pushPositionOf(form);
  1300. error('e', message);
  1301. popPositionOf(save);
  1302. }
  1303. public void errorIfNonEmpty(Object form) {
  1304. if (form != LList.Empty)
  1305. error('e', "invalid improper (dotted) list");
  1306. }
  1307. /** Set the line position of the argument to the current position. */
  1308. public void setLineOf (Expression exp)
  1309. {
  1310. // "Special" QuoteExps may be shared, but the position gets set (in the
  1311. // call to QuoteExp.getInstance at end of re-write) for normal ones.
  1312. if (exp instanceof QuoteExp)
  1313. return;
  1314. if (exp.getLineNumber() <= 0)
  1315. exp.setLocation(this);
  1316. }
  1317. /** Extract a type from the car of a pair. */
  1318. public Type exp2Type(Pair typeSpecPair)
  1319. {
  1320. return exp2Type(typeSpecPair, null, null);
  1321. }
  1322. public Type exp2Type(Pair typeSpecPair, Declaration decl, SyntaxForm syntax)
  1323. {
  1324. Object saved = pushPositionOf(typeSpecPair);
  1325. try
  1326. {
  1327. Expression texp = rewrite_car(typeSpecPair, syntax);
  1328. if (texp instanceof ErrorExp)
  1329. return null;
  1330. Type type = getLanguage().getTypeFor(texp);
  1331. if (type == null)
  1332. {
  1333. try
  1334. {
  1335. Object t = texp.eval(env);
  1336. if (t instanceof Class)
  1337. type = Type.make((Class) t);
  1338. else if (t instanceof Type)
  1339. type = (Type) t;
  1340. }
  1341. catch (Error ex)
  1342. {
  1343. throw ex;
  1344. }
  1345. catch (Throwable ex)
  1346. {
  1347. }
  1348. }
  1349. if (type == null)
  1350. {
  1351. if (texp instanceof ReferenceExp)
  1352. error('e', "unknown type name '"
  1353. + ((ReferenceExp) texp).getName() + '\'');
  1354. else
  1355. error('e',
  1356. "invalid type spec");
  1357. type = Type.errorType;
  1358. }
  1359. if (decl != null)
  1360. decl.setType(texp, type);
  1361. return type;
  1362. }
  1363. finally
  1364. {
  1365. popPositionOf(saved);
  1366. }
  1367. }
  1368. public Expression rewrite_with_position (Object exp, boolean function,
  1369. PairWithPosition pair)
  1370. {
  1371. Object saved = pushPositionOf(pair);
  1372. Expression result;
  1373. try
  1374. {
  1375. if (exp == pair)
  1376. result = rewrite_pair(pair, function); // To avoid a cycle
  1377. else
  1378. result = rewrite (exp, function);
  1379. setLineOf(result);
  1380. }
  1381. finally
  1382. {
  1383. popPositionOf(saved);
  1384. }
  1385. return result;
  1386. }
  1387. public static Object wrapSyntax (Object form, SyntaxForm syntax)
  1388. {
  1389. if (syntax == null || form instanceof Expression)
  1390. return form;
  1391. else
  1392. return SyntaxForms.fromDatumIfNeeded(form, syntax);
  1393. }
  1394. /** Pop from formStack all forms that come after beforeFirst.
  1395. */
  1396. public Values popForms(Pair beforeFirst)
  1397. {
  1398. Object tail = formStack.popTail(beforeFirst);
  1399. if (tail == LList.Empty)
  1400. return Values.empty;
  1401. return new ValuesFromLList((LList) tail);
  1402. }
  1403. public void scanForm (Object st, ScopeExp defs)
  1404. {
  1405. if (st instanceof SyntaxForm)
  1406. {
  1407. SyntaxForm sf = (SyntaxForm) st;
  1408. ScopeExp save_scope = setPushCurrentScope(sf.getScope());
  1409. try
  1410. {
  1411. Pair beforeFirst = formStack.last;
  1412. scanForm(sf.getDatum(), defs);
  1413. pushForm(wrapSyntax(popForms(beforeFirst), sf));
  1414. return;
  1415. }
  1416. finally
  1417. {
  1418. setPopCurrentScope(save_scope);
  1419. }
  1420. }
  1421. if (st instanceof Values)
  1422. {
  1423. if (st == Values.empty)
  1424. st = QuoteExp.voidExp; // From #!void
  1425. else if (st instanceof ValuesFromLList)
  1426. {
  1427. for (Object vs = ((ValuesFromLList) st).values;
  1428. vs != LList.Empty; )
  1429. {
  1430. Pair p = (Pair) vs;
  1431. Object save = pushPositionOf(p);
  1432. scanForm(p.getCar(), defs);
  1433. popPositionOf(save);
  1434. vs = p.getCdr();
  1435. }
  1436. }
  1437. else
  1438. {
  1439. Object[] vals = ((Values) st).getValues();
  1440. for (int i = 0; i < vals.length; i++)
  1441. scanForm(vals[i], defs);
  1442. return;
  1443. }
  1444. }
  1445. if (st instanceof Pair)
  1446. {
  1447. Pair st_pair = (Pair) st;
  1448. Declaration saveContext = macroContext;
  1449. Syntax syntax = null;
  1450. ScopeExp savedScope = current_scope;
  1451. Object savedPosition = pushPositionOf(st);
  1452. if (st instanceof SourceLocator && defs.getLineNumber() < 0)
  1453. defs.setLocation((SourceLocator) st);
  1454. try
  1455. {
  1456. Object obj = st_pair.getCar();
  1457. if (obj instanceof SyntaxForm)
  1458. {
  1459. SyntaxForm sf = (SyntaxForm) st_pair.getCar();
  1460. savedScope = setPushCurrentScope(sf.getScope());
  1461. obj = sf.getDatum();
  1462. }
  1463. Pair p;
  1464. if (obj instanceof Pair
  1465. && (p = (Pair) obj).getCar() == LispLanguage.lookup_sym
  1466. && p.getCdr() instanceof Pair
  1467. && (p = (Pair) p.getCdr()).getCdr() instanceof Pair)
  1468. {
  1469. Expression part1 = rewrite(p.getCar());
  1470. Expression part2 = rewrite_car_for_lookup((Pair) p.getCdr());
  1471. Object value1 = part1.valueIfConstant();
  1472. Object value2 = part2.valueIfConstant();
  1473. if (value1 instanceof Class && value2 instanceof Symbol)
  1474. {
  1475. try
  1476. {
  1477. obj = GetNamedPart.getNamedPart(value1, (Symbol)value2);
  1478. if (obj instanceof Syntax)
  1479. syntax = (Syntax) obj;
  1480. }
  1481. catch (Exception ex)
  1482. {
  1483. obj = null;
  1484. }
  1485. }
  1486. else
  1487. obj = namespaceResolve(part1, part2);
  1488. }
  1489. if (obj instanceof Symbol && ! selfEvaluatingSymbol(obj))
  1490. {
  1491. Expression func = rewrite(obj, 'M');
  1492. if (func instanceof ReferenceExp)
  1493. {
  1494. Declaration decl = ((ReferenceExp) func).getBinding();
  1495. if (decl != null)
  1496. syntax = check_if_Syntax(decl);
  1497. else
  1498. {
  1499. obj = resolve(obj, true);
  1500. if (obj instanceof Syntax)
  1501. syntax = (Syntax) obj;
  1502. }
  1503. }
  1504. }
  1505. // Recognize deferred begin created in scanBody for pendingForms.
  1506. // A seemingly-cleaner (obj instanceof Syntax) causes problems
  1507. // with some Syntax forms, such as define.
  1508. else if (obj == kawa.standard.begin.begin
  1509. || obj == kawa.standard.define_library.define_library_scan)
  1510. syntax = (Syntax) obj;
  1511. }
  1512. finally
  1513. {
  1514. if (savedScope != current_scope)
  1515. setPopCurrentScope(savedScope);
  1516. popPositionOf(savedPosition);
  1517. }
  1518. if (syntax != null)
  1519. {
  1520. String save_filename = getFileName();
  1521. try
  1522. {
  1523. syntax.scanForm(st_pair, defs, this);
  1524. return;
  1525. }
  1526. finally
  1527. {
  1528. macroContext = saveContext;
  1529. }
  1530. }
  1531. }
  1532. pushForm(st);
  1533. }
  1534. /** Recursive helper method for rewrite_body.
  1535. * Scan body for definitions, adding partially macro-expanded
  1536. * expressions into the <code>formStack</code>.
  1537. * @param makeList if true, return a list representation of the scanned
  1538. * forms (not including declarations); else forms are push on formStack
  1539. * @return a list of forms if <code>makeList</code> (possibly wrapped
  1540. * in a <code>SyntaxForm</code>); otherwise <code>null</code>.
  1541. */
  1542. public LList scanBody (Object body, ScopeExp defs, boolean makeList)
  1543. {
  1544. LList list = makeList ? LList.Empty : null;
  1545. Pair lastPair = null;
  1546. while (body != LList.Empty)
  1547. {
  1548. if (body instanceof SyntaxForm)
  1549. {
  1550. SyntaxForm sf = (SyntaxForm) body;
  1551. ScopeExp save_scope = setPushCurrentScope(sf.getScope());
  1552. try
  1553. {
  1554. Pair first = formStack.last;
  1555. LList f = scanBody(sf.getDatum(), defs, makeList);
  1556. if (makeList)
  1557. {
  1558. f = (LList) SyntaxForms.fromDatumIfNeeded(f, sf);
  1559. if (lastPair == null)
  1560. return f;
  1561. lastPair.setCdrBackdoor(f);
  1562. return list;
  1563. }
  1564. pushForm(wrapSyntax(popForms(first), sf));
  1565. return null;
  1566. }
  1567. finally
  1568. {
  1569. setPopCurrentScope(save_scope);
  1570. }
  1571. }
  1572. else if (body instanceof Pair)
  1573. {
  1574. Pair pair = (Pair) body;
  1575. Pair first = formStack.last;
  1576. Object savePos = pushPositionOf(pair);
  1577. scanForm(pair.getCar(), defs);
  1578. popPositionOf(savePos);
  1579. if (getState() == Compilation.PROLOG_PARSED && pendingForm != null)
  1580. {
  1581. // We've seen a require form during the initial pass when
  1582. // we're looking module names. Defer the require and any
  1583. // following forms in this body.
  1584. if (pair.getCar() != pendingForm)
  1585. pair = makePair(pair, pendingForm, pair.getCdr());
  1586. pendingForm = new Pair(kawa.standard.begin.begin, pair);
  1587. if (makeList)
  1588. formStack.pushAll(list);
  1589. return LList.Empty;
  1590. }
  1591. if (makeList)
  1592. {
  1593. Pair last = formStack.lastPair();
  1594. LList nlist = (LList) formStack.popTail(first);
  1595. if (lastPair == null)
  1596. list = nlist;
  1597. else
  1598. lastPair.setCdrBackdoor(nlist);
  1599. if (last != first)
  1600. lastPair = last;
  1601. }
  1602. body = pair.getCdr();
  1603. }
  1604. else
  1605. {
  1606. pushForm(syntaxError("body is not a proper list"));
  1607. break;
  1608. }
  1609. }
  1610. return list;
  1611. }
  1612. public static Pair makePair(Pair pair, Object car, Object cdr)
  1613. {
  1614. if (pair instanceof PairWithPosition)
  1615. return new PairWithPosition((PairWithPosition) pair, car, cdr);
  1616. return new Pair(car, cdr);
  1617. }
  1618. /**
  1619. * Re-write a Scheme 'body' in S-expression format into internal form.
  1620. */
  1621. public Expression rewrite_body (Object exp)
  1622. {
  1623. // NOTE we have both a rewrite_body and a rewriteBody.
  1624. // This is confusing, at the least. FIXME.
  1625. Object saved = pushPositionOf(exp);
  1626. LetExp defs = new LetExp();
  1627. defs.setFlag(LetExp.IS_BODY_SCOPE);
  1628. int renamedAliasOldSize = renamedAliasCount();
  1629. Pair first = formStack.last;
  1630. defs.setOuter(current_scope);
  1631. current_scope = defs;
  1632. try
  1633. {
  1634. LList list = scanBody(exp, defs, true);
  1635. if (list.isEmpty())
  1636. pushForm(syntaxError("body with no expressions"));
  1637. int ndecls = 0;
  1638. for (Declaration decl = defs.firstDecl(); decl != null; decl = decl.nextDecl())
  1639. {
  1640. if (! decl.getFlag(Declaration.IS_DYNAMIC))
  1641. {
  1642. ndecls++;
  1643. decl.setInitValue(QuoteExp.undefined_exp);
  1644. }
  1645. }
  1646. rewriteBody(list);
  1647. int renamedAliasNewSize = renamedAliasCount();
  1648. popRenamedAlias(renamedAliasNewSize - renamedAliasOldSize);
  1649. Expression body = makeBody(first, null);
  1650. setLineOf(body);
  1651. if (ndecls == 0)
  1652. return body;
  1653. defs.setBody(body);
  1654. setLineOf(defs);
  1655. return defs;
  1656. }
  1657. finally
  1658. {
  1659. pop(defs);
  1660. popPositionOf(saved);
  1661. }
  1662. }
  1663. protected void rewriteBody (LList forms)
  1664. {
  1665. while (forms != LList.Empty)
  1666. {
  1667. Pair pair = (Pair) forms;
  1668. Object saved = pushPositionOf(pair);
  1669. try
  1670. {
  1671. rewriteInBody(pair.getCar());
  1672. }
  1673. finally
  1674. {
  1675. popPositionOf(saved);
  1676. }
  1677. forms = (LList) pair.getCdr();
  1678. }
  1679. }
  1680. /** Combine a list of zero or more expression forms into a "body". */
  1681. protected Expression makeBody(Pair head, ScopeExp scope)
  1682. {
  1683. Object tail = formStack.popTail(head);
  1684. int nforms = LList.length(tail);
  1685. if (nforms == 0)
  1686. return QuoteExp.voidExp;
  1687. Pair first = (Pair) tail;
  1688. if (nforms == 1)
  1689. {
  1690. return (Expression) first.getCar();
  1691. }
  1692. else
  1693. {
  1694. Expression[] exps = new Expression[nforms];
  1695. first.toArray(exps);
  1696. if (scope instanceof ModuleExp)
  1697. return new ApplyExp(gnu.kawa.functions.AppendValues.appendValues,
  1698. exps);
  1699. else
  1700. return makeBody(exps);
  1701. }
  1702. }
  1703. public boolean appendBodyValues () { return false; }
  1704. /** Combine a 'body' consisting of a list of expression. */
  1705. public Expression makeBody(Expression[] exps)
  1706. {
  1707. if (appendBodyValues())
  1708. return new ApplyExp(gnu.kawa.functions.AppendValues.appendValues, exps);
  1709. else
  1710. return new BeginExp (exps);
  1711. }
  1712. /** Storage used by noteAccess and processAccesses. */
  1713. ArrayList notedAccess;
  1714. /** Note that we reference name in a given scope.
  1715. * This may be called when defining a macro, at scan-time,
  1716. * and the name may be bound to a declaration we haven't seen yet. */
  1717. public void noteAccess (Object name, ScopeExp scope)
  1718. {
  1719. if (notedAccess == null)
  1720. notedAccess = new ArrayList();
  1721. notedAccess.add(name);
  1722. notedAccess.add(scope);
  1723. }
  1724. /** Check references recorded by noteAccess.
  1725. * Resolve now to a Declaration, and note the access.
  1726. * This is needed in case an exported macro references a private Declaration.
  1727. */
  1728. public void processAccesses ()
  1729. {
  1730. if (notedAccess == null)
  1731. return;
  1732. int sz = notedAccess.size();
  1733. ScopeExp saveScope = current_scope;
  1734. for (int i = 0; i < sz; i += 2)
  1735. {
  1736. Object name = notedAccess.get(i);
  1737. ScopeExp scope = (ScopeExp) notedAccess.get(i+1);
  1738. if (current_scope != scope)
  1739. {
  1740. // I.e. first time do equivalent of setPushCurrentScope
  1741. if (current_scope == saveScope)
  1742. lexical.pushSaveTopLevelRedefs();
  1743. setCurrentScope(scope);
  1744. }
  1745. Declaration decl = (Declaration) lexical.lookup(name, -1);
  1746. if (decl != null && ! decl.getFlag(Declaration.IS_UNKNOWN))
  1747. {
  1748. decl.getContext().currentLambda().capture(decl);
  1749. decl.setCanRead(true);
  1750. decl.setSimple(false);
  1751. decl.setFlag(Declaration.EXTERNAL_ACCESS);
  1752. }
  1753. }
  1754. if (current_scope != saveScope)
  1755. setPopCurrentScope(saveScope);
  1756. }
  1757. public void finishModule(ModuleExp mexp)
  1758. {
  1759. boolean moduleStatic = mexp.isStatic();
  1760. for (Declaration decl = mexp.firstDecl();
  1761. decl != null; decl = decl.nextDecl())
  1762. {
  1763. if (decl.getFlag(Declaration.NOT_DEFINING))
  1764. {
  1765. String msg1 = "'";
  1766. String msg2
  1767. = (decl.getFlag(Declaration.EXPORT_SPECIFIED)
  1768. ? "' exported but never defined"
  1769. : decl.getFlag(Declaration.STATIC_SPECIFIED)
  1770. ? "' declared static but never defined"
  1771. : "' declared but never defined");
  1772. error('e', decl, msg1, msg2);
  1773. }
  1774. if (mexp.getFlag(ModuleExp.EXPORT_SPECIFIED)
  1775. || (generateMainMethod() && ! immediate))
  1776. {
  1777. if (decl.getFlag(Declaration.EXPORT_SPECIFIED))
  1778. {
  1779. if (decl.isPrivate())
  1780. {
  1781. if (decl.getFlag(Declaration.PRIVATE_SPECIFIED))
  1782. error('e', decl,
  1783. "'", "' is declared both private and exported");
  1784. decl.setPrivate(false);
  1785. }
  1786. }
  1787. else if (! kawa.standard.IfFeature.isProvide(decl))
  1788. decl.setPrivate(true);
  1789. }
  1790. if (moduleStatic)
  1791. decl.setFlag(Declaration.STATIC_SPECIFIED);
  1792. else if ((mexp.getFlag(ModuleExp.NONSTATIC_SPECIFIED)
  1793. && ! decl.getFlag(Declaration.STATIC_SPECIFIED))
  1794. || gnu.expr.Compilation.moduleStatic < 0
  1795. || mexp.getFlag(ModuleExp.SUPERTYPE_SPECIFIED))
  1796. decl.setFlag(Declaration.NONSTATIC_SPECIFIED);
  1797. }
  1798. if (mexp.getFlag(ModuleExp.SUPERTYPE_SPECIFIED))
  1799. mexp.setFlag(false, ModuleExp.USE_DEFINED_CLASS);
  1800. }
  1801. public void resolveModule(ModuleExp mexp)
  1802. {
  1803. Expression savePos = new ReferenceExp((Object) null);
  1804. int numPending = pendingImports == null ? 0 : pendingImports.size();
  1805. for (int i = 0; i < numPending; )
  1806. {
  1807. ModuleInfo info = (ModuleInfo) pendingImports.elementAt(i++);
  1808. ScopeExp defs = (ScopeExp) pendingImports.elementAt(i++);
  1809. Expression posExp = (Expression) pendingImports.elementAt(i++);
  1810. Pair beforeGoal = (Pair) pendingImports.elementAt(i++);
  1811. DeclSetMapper mapper = (DeclSetMapper) pendingImports.elementAt(i++);
  1812. if (mexp == defs)
  1813. {
  1814. // process(BODY_PARSED);
  1815. savePos.setLine(this);
  1816. setLine(posExp);
  1817. Pair beforeImports = formStack.last;
  1818. kawa.standard.require.importDefinitions(null, info, mapper,
  1819. formStack, defs, this);
  1820. if (beforeGoal != beforeImports
  1821. && beforeImports != formStack.last)
  1822. {
  1823. // Move forms derived from the import forwards in the list,
  1824. // just following beforeGoal.
  1825. Object firstGoal = beforeGoal.getCdr();
  1826. Object firstImports = beforeImports.getCdr();
  1827. beforeGoal.setCdrBackdoor(firstImports);
  1828. formStack.last.setCdrBackdoor(firstGoal);
  1829. beforeImports.setCdrBackdoor(LList.Empty);
  1830. formStack.last = beforeImports;
  1831. }
  1832. setLine(savePos);
  1833. }
  1834. }
  1835. pendingImports = null;
  1836. setModule(mexp);
  1837. savePos.setLine(this);
  1838. setLine(null, -1, -1);
  1839. Compilation save_comp = Compilation.setSaveCurrent(this);
  1840. try
  1841. {
  1842. Pair firstForm = formStack.getHead();
  1843. rewriteBody((LList) formStack.popTail(firstForm));
  1844. mexp.body = makeBody(firstForm, mexp);
  1845. processAccesses();
  1846. // In immediate mode need to preserve Declaration for current "session".
  1847. if (! immediate)
  1848. lexical.pop(mexp);
  1849. // Patch up renamed exports - see export.
  1850. for (Declaration decl = mexp.firstDecl(); decl != null;
  1851. decl = decl.nextDecl()) {
  1852. if (decl.getSymbol() == null
  1853. && decl.getFlag(Declaration.EXPORT_SPECIFIED)) {
  1854. decl.patchSymbolFromSet();
  1855. }
  1856. }
  1857. }
  1858. finally
  1859. {
  1860. Compilation.restoreCurrent(save_comp);
  1861. setLine(savePos);
  1862. }
  1863. /* DEBUGGING:
  1864. OutPort err = OutPort.errDefault ();
  1865. err.print ("[Re-written expression for load/compile: ");
  1866. mexp.print (err);
  1867. //err.print ("\nbefore load<"+mod.getClass().getName()+">");
  1868. err.println();
  1869. err.flush();
  1870. */
  1871. }
  1872. public Declaration makeRenamedAlias (Declaration decl,
  1873. ScopeExp templateScope)
  1874. {
  1875. if (templateScope == null)
  1876. return decl; // ???
  1877. return makeRenamedAlias(decl.getSymbol(), decl, templateScope);
  1878. }
  1879. public Declaration makeRenamedAlias (Object name,
  1880. Declaration decl,
  1881. ScopeExp templateScope)
  1882. {
  1883. Declaration alias = new Declaration(name);
  1884. alias.setAlias(true);
  1885. alias.setPrivate(true);
  1886. alias.context = templateScope;
  1887. ReferenceExp ref = new ReferenceExp(decl);
  1888. ref.setDontDereference(true);
  1889. alias.noteValue(ref);
  1890. return alias;
  1891. }
  1892. /** Push an alias for a declaration in a scope.
  1893. * If the name of {@code decl} came from a syntax template
  1894. * whose immediate scope is {@code templateScope},
  1895. * then the same syntax template may contain local variable references
  1896. * that are also in the same {@code templateScope}.
  1897. * Such variable references will <em>not</em> look in the current
  1898. * "physical" scope, where we just created {@code decl}, but
  1899. * will instead search the "lexical" {@code templateScope}.
  1900. * So that such references can resolve to {@code decl}, we
  1901. * create an alias in {@code templateScope} that points
  1902. * to {@code decl}. We record that we did this in the
  1903. * {@code renamedAliasStack}, so we can remove the alias later.
  1904. */
  1905. public void pushRenamedAlias (Declaration alias)
  1906. {
  1907. Declaration decl = getOriginalRef(alias).getBinding();
  1908. ScopeExp templateScope = alias.context;
  1909. decl.setSymbol(null);
  1910. Declaration old = templateScope.lookup(alias.getSymbol());
  1911. if (old != null)
  1912. templateScope.remove(old);
  1913. templateScope.addDeclaration(alias);
  1914. if (renamedAliasStack == null)
  1915. renamedAliasStack = new Stack<Declaration>();
  1916. renamedAliasStack.push(old);
  1917. renamedAliasStack.push(alias);
  1918. }
  1919. public int renamedAliasCount() {
  1920. return renamedAliasStack == null ? 0 : renamedAliasStack.size() >> 1;
  1921. }
  1922. /** Remove one or more aliases created by <code>pushRenamedAlias</code>. */
  1923. public void popRenamedAlias (int count)
  1924. {
  1925. while (--count >= 0)
  1926. {
  1927. Declaration alias = (Declaration) renamedAliasStack.pop();
  1928. ScopeExp templateScope = alias.getContext();
  1929. Declaration decl = getOriginalRef(alias).getBinding();
  1930. decl.setSymbol(alias.getSymbol());
  1931. templateScope.remove(alias);
  1932. Declaration old = renamedAliasStack.pop();
  1933. if (old != null)
  1934. templateScope.addDeclaration(old);
  1935. }
  1936. }
  1937. public Declaration define(Object name, ScopeExp defs) {
  1938. return define(name, (TemplateScope) null, defs);
  1939. }
  1940. public Declaration define(Object name, SyntaxForm nameSyntax,
  1941. ScopeExp defs) {
  1942. return define(name, nameSyntax == null ? null : nameSyntax.getScope(),
  1943. defs);
  1944. }
  1945. public Declaration define(Object name, TemplateScope templateScope,
  1946. ScopeExp defs) {
  1947. ScopeExp scope = templateScope != null ? templateScope
  1948. : currentScope();
  1949. boolean aliasNeeded = scope != defs;
  1950. Object declName = aliasNeeded
  1951. ? Symbol.makeUninterned(name.toString())
  1952. : name;
  1953. Declaration decl = defs.getDefine(declName, this);
  1954. if (aliasNeeded) {
  1955. Declaration alias = makeRenamedAlias(name, decl, scope);
  1956. if (defs instanceof LetExp)
  1957. pushRenamedAlias(alias);
  1958. else
  1959. scope.addDeclaration(alias);
  1960. }
  1961. push(decl);
  1962. return decl;
  1963. }
  1964. static boolean isObjectSyntax (ClassType declaringClass, String fieldName)
  1965. {
  1966. return "objectSyntax".equals(fieldName)
  1967. && "kawa.standard.object".equals(declaringClass.getName());
  1968. }
  1969. public FormStack formStack = new FormStack(this);
  1970. public void pushForm(Object value) { formStack.push(value); }
  1971. /** A list of "forms" to be further processed.
  1972. * It is implemented as an LList so we can save position information.
  1973. */
  1974. public static class FormStack extends Pair {
  1975. private Pair last = this;
  1976. SourceLocator sloc;
  1977. public FormStack(SourceLocator sloc) {
  1978. this.sloc = sloc;
  1979. this.cdr = LList.Empty;
  1980. }
  1981. /** Return the "head" of the list.
  1982. * The cdr of the head is the first element.
  1983. */
  1984. public Pair getHead() { return this; }
  1985. public Object getFirst() { return cdr; }
  1986. /** The Pair whose car is the last form in the list.
  1987. * If the list is empty, this returns the list head.
  1988. */
  1989. @Override
  1990. public Pair lastPair() { return last; }
  1991. /* DEBUGGING:
  1992. public void dump() {
  1993. int i=0;
  1994. System.err.println("formStack len:"+LList.length(getFirst()));
  1995. for(Object x = getFirst(); x instanceof Pair; i++) {
  1996. Pair p = (Pair) x;
  1997. //if (! (p.getCar() instanceof SetExp))
  1998. System.err.println("- #"+i+": "+p.getCar());
  1999. x = p.getCdr();
  2000. }
  2001. }
  2002. */
  2003. public Object popTail(Pair oldTail) {
  2004. Object r = oldTail.getCdr();
  2005. oldTail.setCdrBackdoor(LList.Empty);
  2006. last = oldTail;
  2007. return r;
  2008. }
  2009. public void push(Object value) {
  2010. PairWithPosition pair = new PairWithPosition(sloc, value, LList.Empty);
  2011. last.setCdrBackdoor(pair);
  2012. last = pair;
  2013. }
  2014. public void pushAll(LList values) {
  2015. if (values == LList.Empty)
  2016. return;
  2017. last.setCdrBackdoor(values);
  2018. last = ((Pair) values).lastPair();
  2019. }
  2020. public void pushAll(LList values, Pair valuesLast) {
  2021. if (values == LList.Empty)
  2022. return;
  2023. last.setCdrBackdoor(values);
  2024. last = valuesLast;
  2025. }
  2026. public void pushAfter(Object value, Pair position) {
  2027. Pair pair = new PairWithPosition(sloc, value, position.getCdr());
  2028. position.setCdrBackdoor(pair);
  2029. if (last == position)
  2030. last = pair;
  2031. }
  2032. }
  2033. /** An implementationof Values using a linked list.
  2034. */
  2035. public static class ValuesFromLList extends Values.FromList<Object> {
  2036. public LList values;
  2037. public ValuesFromLList(LList values) {
  2038. super(values);
  2039. this.values = values;
  2040. }
  2041. }
  2042. Stack<ScanContext> scanContextStack = new Stack<ScanContext>();
  2043. public ScanContext getScanContext() { return scanContextStack.peek(); }
  2044. public int curScanNesting() { return scanContextStack.size(); }
  2045. public Stack<ScanContext> getScanContextStack() { return scanContextStack; }
  2046. public void pushScanContext (LambdaExp lambda) {
  2047. ScanContext newContext = new ScanContext();
  2048. newContext.lambda = lambda;
  2049. scanContextStack.push(newContext);
  2050. }
  2051. public void popScanContext() {
  2052. scanContextStack.pop();
  2053. }
  2054. public static class ScanContext {
  2055. LinkedHashMap<Declaration,Declaration> decls
  2056. = new LinkedHashMap<Declaration,Declaration>();
  2057. ArrayList<Expression> scanExpressions = null;
  2058. LambdaExp lambda;
  2059. public LambdaExp getLambda() { return lambda; }
  2060. public Declaration addSeqDecl(Declaration scanVar) {
  2061. Declaration param = decls.get(scanVar);
  2062. if (param == null) {
  2063. param = lambda.addParameter(null);
  2064. decls.put(scanVar, param);
  2065. }
  2066. return param;
  2067. }
  2068. public void addSeqExpression(Expression scanExp) {
  2069. if (scanExpressions == null)
  2070. scanExpressions = new ArrayList<Expression>();
  2071. scanExpressions.add(scanExp);
  2072. }
  2073. }
  2074. }