00001: package clogs.staticanalysis;
00002:
00003: import java.util.NoSuchElementException;
00004:
00005: import clogs.ast.*;
00006: import clogs.codegen.CodeGen;
00007: import clogs.util.List;
00008: import clogs.util.Map;
00009: import clogs.util.Optional;
00010:
00011:
00012: public class Context
00013: {
00014: protected final Map<String, Type> variableTypes;
00015: protected final Map<String, FunDefSig> fundefsigs;
00016: protected final Map<String, String> variableLocations;
00017: protected final int paramCounter;
00018: protected final int localVariableCounter;
00019:
00020:
00021: public static final Context emptyContext =
00022: new Context (Map.<String, Type>empty (), Map.<String, FunDefSig>empty (), Map.<String, String>empty (), 2, -1);
00023:
00024:
00025: protected Context (Map<String, Type> variableTypes, Map<String, FunDefSig> fundefsigs, Map<String, String> variableLocations,
00026: int paramCounter, int localVariableCounter)
00027: {
00028: this.variableTypes = variableTypes;
00029: this.fundefsigs = fundefsigs;
00030: this.variableLocations = variableLocations;
00031: this.paramCounter = paramCounter;
00032: this.localVariableCounter = localVariableCounter;
00033: }
00034:
00035:
00036: public String getVariableLocation (String name)
00037: {
00038: String location = variableLocations.get (name);
00039: if (location == null) {
00040: throw new NoSuchElementException ("Variable " + name + " not found in context " + this);
00041: }
00042: return location;
00043: }
00044:
00045:
00046: public boolean containsVariable (String name)
00047: {
00048: Type type = variableTypes.get (name);
00049: return type != null;
00050: }
00051:
00052:
00053: public Type getVariableType (String name)
00054: {
00055: Type type = variableTypes.get (name);
00056: if (type == null) {
00057: throw new NoSuchElementException ("Variable " + name + " not found in context " + this);
00058: }
00059: return type;
00060: }
00061:
00062:
00063: public boolean containsFunDefSig (String name)
00064: {
00065: FunDefSig fundefsig = fundefsigs.get (name);
00066: return fundefsig != null;
00067: }
00068:
00069:
00070: public FunDefSig getFunDefSig (String name)
00071: {
00072: FunDefSig fundefsig = fundefsigs.get (name);
00073: if (fundefsig == null) {
00074: throw new NoSuchElementException ("Function definition signature " + name + " not found in context " + this);
00075: }
00076: return fundefsig;
00077: }
00078:
00079:
00080: public Context addGlobalVariables (List<Decl> decls)
00081: {
00082: Map<String, Type> variableTypesNew = variableTypes;
00083: Map<String, String> variableLocationsNew = variableLocations;
00084: for (Decl decl : decls) {
00085: if (variableTypesNew.get (decl.name) != null) {
00086: throw new RuntimeException ("Variable " + decl.name + " already found in context " + this);
00087: }
00088: variableTypesNew = variableTypesNew.add (decl.name, decl.type);
00089: variableLocationsNew = variableLocationsNew.add (decl.name, decl.name);
00090: }
00091: return new Context (variableTypesNew, fundefsigs, variableLocationsNew, paramCounter, localVariableCounter);
00092: }
00093:
00094:
00095: public Context addFunParams (FunDefSig fundefsig)
00096: {
00097: assert (paramCounter == 2);
00098: int paramCounterTmp = paramCounter;
00099: Map<String, Type> variableTypesNew = variableTypes;
00100: Map<String, String> variableLocationsNew = variableLocations;
00101: for (Decl decl : fundefsig.params) {
00102: if (variableTypesNew.get (decl.name) != null) {
00103: throw new RuntimeException ("Variable " + decl.name + " already found in context " + this);
00104: }
00105: variableTypesNew = variableTypesNew.add (decl.name, decl.type);
00106: variableLocationsNew = variableLocationsNew.add (decl.name, (CodeGen.intSize * paramCounterTmp++) + "(%ebp)");
00107: }
00108: return new Context (variableTypesNew, fundefsigs, variableLocationsNew, paramCounterTmp, localVariableCounter);
00109: }
00110:
00111:
00112: public Context addLocalVariables (List<Decl> decls)
00113: {
00114: int localVariableCounterTmp = localVariableCounter;
00115: Map<String, Type> variableTypesNew = variableTypes;
00116: Map<String, String> variableLocationsNew = variableLocations;
00117: for (Decl decl : decls) {
00118: if (variableTypesNew.get (decl.name) != null) {
00119: throw new RuntimeException ("Variable " + decl.name + " already found in context " + this);
00120: }
00121: variableTypesNew = variableTypesNew.add (decl.name, decl.type);
00122: variableLocationsNew = variableLocationsNew.add (decl.name, (CodeGen.intSize * localVariableCounterTmp--) + "(%ebp)");
00123: }
00124: return new Context (variableTypesNew, fundefsigs, variableLocationsNew, paramCounter, localVariableCounterTmp);
00125: }
00126:
00127:
00128: public Context addFunDefSig (FunDefSig fundefsig)
00129: {
00130: if (fundefsigs.get (fundefsig.name) != null) {
00131: throw new RuntimeException ("Function definition signature " + fundefsig.name + " already found in context " + this);
00132: }
00133: return new Context (variableTypes, fundefsigs.add (fundefsig.name, fundefsig), variableLocations, paramCounter, localVariableCounter);
00134: }
00135:
00136:
00137: public Context addFunDefSigs (List<FunDefSig> fundefsigs)
00138: {
00139: Context context = this;
00140: for (FunDefSig fundefsig : fundefsigs) {
00141: context = context.addFunDefSig (fundefsig);
00142: }
00143: return context;
00144: }
00145:
00146:
00147: public Context addFunDefs (List<FunDef> fundefs)
00148: {
00149: Context context = this;
00150: for (FunDef fundef : fundefs) {
00151: context = context.addFunDefSig (fundef);
00152: }
00153: return context;
00154: }
00155:
00156:
00157: public String toString ()
00158: {
00159: boolean first;
00160: StringBuffer sb = new StringBuffer ();
00161: first = true;
00162: sb.append ("variables: ");
00163: for (String var : variableTypes.keyList ()) {
00164: if (!first) {
00165: sb.append (", ");
00166: }
00167: first = false;
00168: Type type = variableTypes.get (var);
00169: String location = variableLocations.get (var);
00170: sb.append (var);
00171: sb.append (" :: ");
00172: sb.append (type);
00173: sb.append (" @ ");
00174: sb.append (location);
00175: }
00176: sb.append ("; ");
00177: first = true;
00178: for (String funName : fundefsigs.keyList ()) {
00179: if (!first) {
00180: sb.append (", ");
00181: }
00182: first = false;
00183: FunDefSig fundefsig = fundefsigs.get (funName);
00184: sb.append (fundefsig.type);
00185: sb.append (" ");
00186: sb.append (fundefsig.name);
00187: sb.append (" (");
00188: sb.append (fundefsig.params);
00189: sb.append (")");
00190: }
00191: sb.append ("; paramCounter = ");
00192: sb.append (paramCounter);
00193: sb.append (")");
00194: return sb.toString ();
00195: }
00196: }
00197:
00198:
|