001: // Copyright (C) 2000 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ../../COPYING.
003:
004: package kawa.standard;
005:
006: import kawa.lang.*;
007: import gnu.lists.*;
008: import gnu.expr.*;
009: import gnu.math.*;
010: import gnu.bytecode.*;
011:
012: public class define_unit extends Syntax {
013: public static final define_unit define_unit = new define_unit(false);
014: static {
015: define_unit.setName("define-unit");
016: }
017: public static final define_unit define_base_unit = new define_unit(
018: true);
019: static {
020: define_base_unit.setName("define-base-unit");
021: }
022:
023: /** True if this is define-base-unit, false if define-unit. */
024: boolean base;
025:
026: public define_unit(boolean base) {
027: this .base = base;
028: }
029:
030: public boolean scanForDefinitions(Pair st, java.util.Vector forms,
031: ScopeExp defs, Translator tr) {
032: if (st.cdr instanceof Pair) {
033: Pair p = (Pair) st.cdr;
034: Object q = p.car;
035: if (q instanceof String) {
036: String name = (String) q;
037: String sym = (name + "$unit").intern();
038: Declaration decl = defs.getDefine(sym, 'w', tr);
039: tr.push(decl);
040: Translator.setLine(decl, p);
041: decl.setFlag(Declaration.IS_CONSTANT);
042: if (defs instanceof ModuleExp)
043: decl.setCanRead(true);
044: Unit unit = null;
045: if (base && p.cdr == LList.Empty)
046: unit = BaseUnit.make(name, (String) null);
047: else if (p.cdr instanceof Pair) {
048: Object v = ((Pair) p.cdr).car;
049: if (base && v instanceof FString)
050: unit = BaseUnit.make(name, v.toString());
051: else if (!base && v instanceof Quantity)
052: unit = Unit.make(name, (Quantity) v);
053: }
054: if (unit != null)
055: decl.noteValue(new QuoteExp(unit));
056: p = Translator.makePair(p, decl, p.cdr);
057: st = Translator.makePair(st, this , p);
058: forms.addElement(st);
059: return true;
060: }
061: }
062: tr.error('e', "missing name in define-unit");
063: return false;
064: }
065:
066: public Expression rewriteForm(Pair form, Translator tr) {
067: Object obj = form.cdr;
068: Expression value = null;
069: Pair p1;
070:
071: if (!(obj instanceof Pair)
072: || !((p1 = (Pair) obj).car instanceof Declaration))
073: return tr.syntaxError("invalid syntax for " + getName());
074: Declaration decl = (Declaration) p1.car;
075: String name = decl.getName();
076: String unit = name.substring(0, name.length() - 5).intern(); // Drop $unit.
077: ClassType unitType = ClassType.make("gnu.math.Unit");
078: decl.setType(unitType);
079: if ((value = decl.getValue()) instanceof QuoteExp
080: && ((QuoteExp) value).getValue() instanceof Unit)
081: ;
082: else if (base) {
083: String dimension = null;
084: if (p1.cdr != LList.Empty) {
085: dimension = ((Pair) p1.cdr).car.toString();
086: }
087: BaseUnit bunit = BaseUnit.make(unit, dimension);
088: value = new QuoteExp(bunit);
089: } else {
090: if (!(p1.cdr instanceof Pair))
091: return tr.syntaxError("missing value for define-unit");
092: Pair p2 = (Pair) p1.cdr;
093: value = tr.rewrite(p2.car);
094: Object quantity;
095: if (value instanceof QuoteExp
096: && (quantity = ((QuoteExp) value).getValue()) instanceof Quantity) {
097: value = new QuoteExp(Unit.make(unit,
098: (Quantity) quantity));
099: } else {
100: Expression[] args = new Expression[2];
101: args[0] = new QuoteExp(unit);
102: args[1] = value;
103: value = gnu.kawa.reflect.Invoke.makeInvokeStatic(
104: unitType, "make", args);
105: }
106: }
107: SetExp sexp = new SetExp(decl, value);
108: sexp.setDefining(true);
109: decl.noteValue(value);
110: return sexp;
111: }
112: }
|