public ISemantReturn<ExprType> GetExprType(Env env) {
Boolean isConst = this.TypeQuals.Contains(TypeQual.CONST);
Boolean isVolatile = this.TypeQuals.Contains(TypeQual.VOLATILE);
// If no Type specifier is given, assume long Type.
if (this.TypeSpecs.IsEmpty) {
return SemantReturn.Create(env, new LongType(isConst, isVolatile));
}
// If every Type specifier is basic, go to the lookup table.
if (this.TypeSpecs.All(typeSpec => typeSpec.Kind != TypeSpecKind.NON_BASIC)) {
var basicTypeSpecKinds =
this.TypeSpecs
.ConvertAll(typeSpec => typeSpec.Kind)
.Distinct()
.ToImmutableSortedSet();
foreach (var pair in BasicTypeSpecLookupTable) {
if (pair.Key.SetEquals(basicTypeSpecKinds)) {
return SemantReturn.Create(env, pair.Value);
}
}
throw new InvalidOperationException("Invalid Type specifier set.");
}
// If there is a non-basic Type specifier, semant it.
if (this.TypeSpecs.Count != 1) {
throw new InvalidOperationException("Invalid Type specifier set.");
}
var type = Semant(this.TypeSpecs[0].GetExprType, ref env);
return SemantReturn.Create(env, type.GetQualifiedType(isConst, isVolatile));
}
}