001: /**************************************************************************/
002: /* N I C E */
003: /* A high-level object-oriented research language */
004: /* (c) Daniel Bonniot 2000 */
005: /* */
006: /* This program is free software; you can redistribute it and/or modify */
007: /* it under the terms of the GNU General Public License as published by */
008: /* the Free Software Foundation; either version 2 of the License, or */
009: /* (at your option) any later version. */
010: /* */
011: /**************************************************************************/package bossa.syntax;
012:
013: import java.util.*;
014: import bossa.util.*;
015:
016: import mlsub.typing.Polytype;
017: import mlsub.typing.Monotype;
018:
019: /**
020: An expression of the Nice language.
021:
022: Subclasses of Expression have the 'Exp' suffix in their name.
023:
024: @version $Date: 2005/01/15 20:27:33 $
025: @author Daniel Bonniot (d.bonniot@mail.dotcom.fr)
026: */
027: public abstract class Expression implements Located, Printable {
028: /** @return true iff this expression can be assigned a value. */
029: public boolean isAssignable() {
030: return false;
031: }
032:
033: boolean isZero() {
034: return false;
035: }
036:
037: boolean isFalse() {
038: return false;
039: }
040:
041: boolean isTrue() {
042: return false;
043: }
044:
045: public boolean isNull() {
046: return false;
047: }
048:
049: /**
050: * Resolve overloading, assuming that this expression
051: * should have some Type.
052: *
053: * @param expectedType the type this expression should have.
054: * @return the resolved expression. Doesn't return if OR is not possible.
055: */
056: Expression resolveOverloading(Polytype expectedType) {
057: // Default implementation: do not consider the expected type.
058: return noOverloading();
059: }
060:
061: /**
062: * No overloading information is known,
063: * just checks there is only one alternative.
064: *
065: * @return the resolved expression. Doesn't return if OR is not possible.
066: */
067: Expression noOverloading() {
068: return this ;
069: }
070:
071: /**
072: Called with the type that this expression is expected to have.
073: This information can be used to generate better code.
074: */
075: void adjustToExpectedType(Monotype expectedType) {
076: // Default: do nothing.
077: }
078:
079: static void adjustToExpectedType(Expression[] expressions,
080: Monotype[] types) {
081: // The domain of a function can be null in rare circumstances, like
082: // for a function of type <T> T
083: if (types == null)
084: return;
085:
086: for (int i = 0; i < types.length; i++)
087: expressions[i].adjustToExpectedType(types[i]);
088: }
089:
090: /** computes the static type of the expression */
091: abstract void computeType();
092:
093: public Polytype getType() {
094: if (type == null) {
095: computeType();
096: }
097: if (type == null)
098: Debug.println(this + "(" + this .getClass()
099: + ") has null type");
100:
101: return type;
102: }
103:
104: /**
105: * Maps getType over a collection of Expressions
106: *
107: * @param Expressions the list of Expressions
108: * @return the list of their PolyTypes
109: */
110: static Polytype[] getType(Expression[] expressions) {
111: Polytype[] res = new Polytype[expressions.length];
112:
113: for (int i = 0; i < expressions.length; i++) {
114: //why has this different behavior compared to the previous method???
115: expressions[i] = expressions[i].noOverloading();
116: res[i] = expressions[i].getType();
117: }
118:
119: return res;
120: }
121:
122: Polytype inferredReturnType() {
123: Internal.error("inferredReturnType called in " + getClass());
124: return null;
125: }
126:
127: void checkSpecialRequirements(Expression[] arguments) {
128: // Do nothing by default.
129: }
130:
131: public void setLocation(Location l) {
132: location = l;
133: }
134:
135: public final Location location() {
136: return location;
137: }
138:
139: // from interface bossa.util.Printable
140: public String toString(int param) {
141: // default implementation
142: return toString();
143: }
144:
145: private Location location = Location.nowhere();
146: protected Polytype type;
147: }
|