001: package kawa.standard;
002:
003: import kawa.lang.*;
004: import gnu.expr.*;
005: import gnu.lists.*;
006: import java.util.Stack;
007:
008: public class with_compile_options extends Syntax {
009: public static final with_compile_options with_compile_options = new with_compile_options();
010: static {
011: with_compile_options.setName("with-compile-options");
012: }
013:
014: public void scanForm(Pair form, ScopeExp defs, Translator tr) {
015: Stack stack = new Stack();
016: Object rest = getOptions(form.cdr, stack, this , tr);
017: if (rest == LList.Empty)
018: return;
019: if (rest == form.cdr) {
020: tr.scanBody(rest, defs, false);
021: return;
022: }
023: rest = tr.scanBody(rest, defs, true);
024: rest = new Pair(stack, rest);
025: tr.currentOptions.popOptionValues(stack);
026: tr.formStack.add(Translator.makePair(form, form.car, rest));
027: }
028:
029: public static Object getOptions(Object form, Stack stack,
030: Syntax command, Translator tr) {
031: boolean seenKey = false;
032: gnu.text.Options options = tr.currentOptions;
033: SyntaxForm syntax = null;
034: for (;;) {
035: while (form instanceof SyntaxForm) {
036: syntax = (SyntaxForm) form;
037: form = syntax.form;
038: }
039: if (!(form instanceof Pair))
040: break;
041: Pair pair = (Pair) form;
042: Object pair_car = Translator.stripSyntax(pair.car);
043: if (!(pair_car instanceof Keyword))
044: break;
045: String key = ((Keyword) pair_car).getName();
046: seenKey = true;
047: Object savePos = tr.pushPositionOf(pair);
048: try {
049: form = pair.cdr;
050: while (form instanceof SyntaxForm) {
051: syntax = (SyntaxForm) form;
052: form = syntax.form;
053: }
054: if (!(form instanceof Pair)) {
055: tr.error('e', "keyword " + key
056: + " not followed by value");
057: return LList.Empty;
058: }
059: pair = (Pair) form;
060: Object value = Translator.stripSyntax(pair.car);
061: form = pair.cdr;
062: Object oldValue = options.getLocal(key);
063: if (options.getInfo(key) == null) {
064: tr.error('w', "unknown compile option: " + key);
065: continue;
066: }
067: if (value instanceof FString)
068: value = value.toString();
069: else if (value instanceof Boolean
070: || value instanceof Number)
071: ;
072: else {
073: value = null;
074: tr.error('e', "invalid literal value for key "
075: + key);
076: }
077: options.set(key, value, tr.getMessages());
078: if (stack != null) {
079: stack.push(key);
080: stack.push(oldValue);
081: stack.push(value);
082: }
083: } finally {
084: tr.popPositionOf(savePos);
085: }
086: }
087: if (!seenKey)
088: tr.error('e', "no option keyword in " + command.getName());
089: return Translator.wrapSyntax(form, syntax);
090: }
091:
092: public Expression rewriteForm(Pair form, Translator tr) {
093: Object rest;
094: Stack stack;
095: Object obj = form.cdr;
096: Pair p;
097: if (obj instanceof Pair
098: && (p = (Pair) obj).car instanceof Stack) {
099: stack = (Stack) p.car;
100: rest = p.cdr;
101: tr.currentOptions.pushOptionValues(stack);
102: } else {
103: stack = new Stack();
104: rest = getOptions(obj, stack, this , tr);
105: }
106:
107: try {
108: Expression result = tr.rewrite_body(rest);
109: BeginExp bresult;
110: if (result instanceof BeginExp)
111: bresult = (BeginExp) result;
112: else
113: bresult = new BeginExp(new Expression[] { result });
114: bresult.setCompileOptions(stack);
115: return bresult;
116: } finally {
117: tr.currentOptions.popOptionValues(stack);
118: }
119: }
120: }
|