define_unit.java 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright (C) 2000, 2007 Per M.A. Bothner.
  2. // This is free software; for terms and warranty disclaimer see ../../COPYING.
  3. package kawa.standard;
  4. import gnu.bytecode.*;
  5. import gnu.expr.*;
  6. import gnu.kawa.lispexpr.LispLanguage;
  7. import gnu.lists.*;
  8. import gnu.mapping.*;
  9. import gnu.math.*;
  10. import kawa.lang.*;
  11. public class define_unit extends Syntax
  12. {
  13. public static final define_unit define_unit = new define_unit(false);
  14. static { define_unit.setName("define-unit"); }
  15. public static final define_unit define_base_unit = new define_unit(true);
  16. static { define_base_unit.setName("define-base-unit"); }
  17. /** True if this is define-base-unit, false if define-unit. */
  18. boolean base;
  19. public define_unit (boolean base)
  20. {
  21. this.base = base;
  22. }
  23. @Override
  24. public boolean scanForDefinitions(Pair st, ScopeExp defs, Translator tr)
  25. {
  26. if (st.getCdr() instanceof Pair)
  27. {
  28. Pair p = (Pair) st.getCdr();
  29. Object q = p.getCar();
  30. if (q instanceof SimpleSymbol)
  31. {
  32. String name = q.toString();
  33. Symbol sym = LispLanguage.unitNamespace.getSymbol(name);
  34. Declaration decl = defs.getDefine(sym, tr);
  35. tr.push(decl);
  36. Translator.setLine(decl, p);
  37. decl.setFlag(Declaration.IS_CONSTANT);
  38. if (defs instanceof ModuleExp)
  39. decl.setCanRead(true);
  40. Unit unit = null;
  41. if (base && p.getCdr() == LList.Empty)
  42. unit = BaseUnit.make(name, (String) null);
  43. else if (p.getCdr() instanceof Pair)
  44. {
  45. Object v = ((Pair) p.getCdr()).getCar();
  46. if (base &&
  47. /* #ifdef use:java.lang.CharSequence */
  48. v instanceof CharSequence
  49. /* #else */
  50. // (v instanceof String || v instanceof CharSeq)
  51. /* #endif */
  52. )
  53. unit = BaseUnit.make(name, v.toString());
  54. else if (! base && v instanceof Quantity)
  55. unit = Unit.make(name, (Quantity) v);
  56. }
  57. if (unit != null)
  58. decl.noteValue(new QuoteExp(unit));
  59. p = Translator.makePair(p, decl, p.getCdr());
  60. st = Translator.makePair(st, this, p);
  61. tr.pushForm(st);
  62. return true;
  63. }
  64. }
  65. tr.error('e', "missing name in define-unit");
  66. return false;
  67. }
  68. public Expression rewriteForm (Pair form, Translator tr)
  69. {
  70. Object obj = form.getCdr();
  71. Expression value = null;
  72. Pair p1;
  73. if (! (obj instanceof Pair)
  74. || ! ((p1 = (Pair) obj).getCar() instanceof Declaration))
  75. return tr.syntaxError ("invalid syntax for "+getName());
  76. Declaration decl = (Declaration) p1.getCar();
  77. Symbol symbol = (Symbol) decl.getSymbol();
  78. String unit = symbol.getLocalPart();
  79. ClassType unitType = ClassType.make("gnu.math.Unit");
  80. decl.setType(unitType);
  81. if ((value = decl.getValue()) instanceof QuoteExp
  82. && ((QuoteExp) value).getValue() instanceof Unit)
  83. ;
  84. else if (base)
  85. {
  86. String dimension = null;
  87. if (p1.getCdr() != LList.Empty)
  88. {
  89. dimension = ((Pair) p1.getCdr()).getCar().toString();
  90. }
  91. BaseUnit bunit = BaseUnit.make(unit, dimension);
  92. value = new QuoteExp(bunit);
  93. }
  94. else
  95. {
  96. if (! (p1.getCdr() instanceof Pair))
  97. return tr.syntaxError("missing value for define-unit");
  98. Pair p2 = (Pair) p1.getCdr();
  99. value = tr.rewrite (p2.getCar());
  100. Object quantity;
  101. if (value instanceof QuoteExp
  102. && (quantity = ((QuoteExp) value).getValue()) instanceof Quantity)
  103. {
  104. value = new QuoteExp(Unit.make(unit, (Quantity) quantity));
  105. }
  106. else
  107. {
  108. Expression[] args = new Expression[2];
  109. args[0] = new QuoteExp(unit);
  110. args[1] = value;
  111. value = gnu.kawa.reflect.Invoke.makeInvokeStatic(unitType, "make",
  112. args);
  113. }
  114. }
  115. SetExp sexp = new SetExp(decl, value);
  116. sexp.setDefining (true);
  117. decl.noteValue(value);
  118. return sexp;
  119. }
  120. }