## types.pkg
## (C) 2001 Lucent Technologies, Bell Labs
# Compiled by:
#
src/lib/compiler/front/typer-stuff/typecheckdata.sublib# Datastructures describing type declarations.
#
# In particular,
#
# Typ
#
# provides the value type bound by the symbol table
# for that namespace -- see OVERVIEW section in
#
#
src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg# NB: In general we avoid plurals in package names,
# but we use the plural in this case to sidestep
# the problem that 'type' is a reserved word. XXX BUGGO FIXME -- except that 'type' is no longer reserved! ;-)
stipulate
package ip = inverse_path; # inverse_path is from
src/lib/compiler/front/typer-stuff/basics/symbol-path.pkg package mp = stamppath; # stamppath is from
src/lib/compiler/front/typer-stuff/modules/stamppath.pkg package ph = picklehash; # picklehash is from
src/lib/compiler/front/basics/map/picklehash.pkg package pl = property_list; # property_list is from
src/lib/src/property-list.pkg package sta = stamp; # stamp is from
src/lib/compiler/front/typer-stuff/basics/stamp.pkg package sy = symbol; # symbol is from
src/lib/compiler/front/basics/map/symbol.pkg package vh = varhome; # varhome is from
src/lib/compiler/front/typer-stuff/basics/varhome.pkgherein
package types
: (weak) Types # Types is from
src/lib/compiler/front/typer-stuff/types/types.api {
Label = sy::Symbol;
Type_Scheme_Arg_Eq_Properties
=
List( Bool ); # equality property indicator
package eq_type { # Give YES/NO/... their own little namespace.
#
Data
= YES
| NO
| INDETERMINATE
# This was "IND", which I'm guessing is cryptic for "INDETERMINATE" -- 2009-03-21 CrT
| CHUNK
| DATA
| EQ_ABSTRACT
# Used to implement "abstype" statements.
| UNDEF
;
};
Literal_Kind
=
INT
| UNT | FLOAT | CHAR | STRING;
Type_Variable # User-specified type variables like X.
= USER_TYPE_VARIABLE {
name: sy::Symbol, # A type variable symbol.
eq: Bool, # Must it resolve to an 'equality type'?
fn_nesting: Int # Outermost fun/fn lexical context mentioning/using us.
}
| META_TYPE_VARIABLE {
eq: Bool, # Must it resolve to an 'equality type'?
fn_nesting: Int # Outermost fun/fn lexical context mentioning/using us.
# fn_nesting = infinity for META-args
# fn_nesting < infinity for lambda bound
}
| INCOMPLETE_RECORD_TYPE_VARIABLE {
known_fields: List( (Label, Type) ),
eq: Bool, # Must it resolve to an 'equality type'?
fn_nesting: Int # Outermost fun/fn lexical context mentioning/using us.
}
| RESOLVED_TYPE_VARIABLE Type
# A type variable for which we have inferred a type.
| OVERLOADED_TYPE_VARIABLE Bool
# Overloaded operator type scheme variable:
# arg is TRUE if it must resolve to an equality type.
| LITERAL_TYPE_VARIABLE
# Used to resolve type of a type-agnostic literal.
{ kind: Literal_Kind,
source_code_region: line_number_db::Source_Code_Region
}
| TYPE_VARIABLE_MARK Int
also
Typ_Path
= TYPPATH_VARIABLE Exception
| TYPPATH_TYP Typ
| TYPPATH_GENERIC (List(Typ_Path), List(Typ_Path))
| TYPPATH_APPLY (Typ_Path, List(Typ_Path))
| TYPPATH_SELECT (Typ_Path, Int)
also
Typ_Kind
= BASE Int
| DATATYPE
{ index: Int,
stamps: Vector( sta::Stamp ),
root: Null_Or( sta::Stamp ), # The root field used by type spec only.
free_typs: List( Typ ),
family: Datatype_Family
}
| ABSTRACT Typ
| FORMAL
# Used only inside apis
| TEMP
# Used only during enum elaborations
| FLEXIBLE_TYP Typ_Path
# Macro expanded formal type constructor
# Nomenclature: "Definition of SML" calls typcons from apis "flexible" an all others "rigid".
also
Typ # Typ is the referent for symbolmapstack_entry::Symbolmapstack_Entry.NAMED_TYPE
= PLAIN_TYP Plain_Typ_Record
| DEFINED_TYP
{ stamp: sta::Stamp,
type_scheme: Type_Scheme,
strict: List( Bool ),
path: ip::Inverse_Path
}
| TYP_BY_STAMPPATH
# Used only inside apis
{ arity: Int,
stamppath: mp::Stamppath,
path: ip::Inverse_Path
}
| RECORD_TYP List( Label )
| RECURSIVE_TYPE Int
# Used only in domain type of Constructor_Description
| FREE_TYPE Int
# Used only in domain type of Constructor_Description
| ERRONEOUS_TYP
also
Type
= TYPE_VARIABLE_REF Typevar_Ref
| TYPE_SCHEME_ARG_I Int
# i-th argument to a type function.
| WILDCARD_TYPE
| UNDEFINED_TYPE
| TYPCON_TYPE (Typ, List(Type))
| TYPE_SCHEME_TYPE
{ type_scheme_arg_eq_properties: Type_Scheme_Arg_Eq_Properties,
type_scheme: Type_Scheme
}
also
Type_Scheme
= TYPE_SCHEME
{ arity: Int,
body: Type
}
withtype
Typevar_Ref
=
{ ref_typevar: Ref( Type_Variable ),
id: Int # Purely for debuggging printout purposes.
}
also
Constructor_Description # Used in Datatype_Member
=
{ name: sy::Symbol,
form: vh::Valcon_Form,
domain: Null_Or( Type )
}
# A member of a family of (potentially) mutually recursive datatypes
also
Datatype_Member
=
{ typ_name: sy::Symbol,
arity: Int,
eqtype_info: Ref( eq_type::Data ), # Records whether this is/isn't/might-be/... an "equality type".
is_lazy: Bool,
constructor_list: List( Constructor_Description ),
an_api: vh::Valcon_Signature
}
also
Datatype_Family
=
{ mkey: sta::Stamp, # "member key"...?
members: Vector( Datatype_Member ),
property_list: pl::Property_List
}
also
Stub_Info
=
{ owner: ph::Picklehash,
is_lib: Bool
}
also
Plain_Typ_Record # Plain_Typ_Record is the referent for stammapstack::Stampmapstack.typ_map, module_level_declarations::Modtree.PLAIN_TYP_MODTREE_NODE
=
{ stamp: sta::Stamp,
arity: Int,
eqtype_info: Ref( eq_type::Data ), # YES/NO/... Records what we know about legality of equality comparisons on this type.
#
kind: Typ_Kind,
path: ip::Inverse_Path,
stub: Null_Or( Stub_Info )
};
debugging = typer_data_controls::types_debugging; # REF FALSE
stipulate
#
next_type_var_id = REF 0; # Used purely for debugging printout purposes.
#
herein
#
fun allocate_type_variable_id ()
=
{ id = *next_type_var_id;
next_type_var_id := id + 1;
id;
};
fun make_type_variable_ref
( typevar: Type_Variable,
stack: List(String)
)
:
Typevar_Ref
=
{ if *debugging
printf "make_type_variable_ref making typevar_ref id%d for %s\n" *next_type_var_id (string::join "" (reverse stack));
fi;
#
{ ref_typevar => REF typevar,
id => allocate_type_variable_id()
};
};
fun make_type_variable_ref'
( ref_typevar: Ref( Type_Variable ),
stack: List(String)
)
:
Typevar_Ref
=
{ if *debugging
printf "make_type_variable_ref' making typevar_ref id%d for %s\n" *next_type_var_id (string::join "" (reverse stack));
fi;
#
{ id => allocate_type_variable_id (),
ref_typevar
};
};
end;
fun copy_type_variable_ref ({ ref_typevar, ... }: Typevar_Ref)
=
{ ref_typevar => REF *ref_typevar,
id => allocate_type_variable_id()
};
infinity = 10000000; # Now you know. :)
Valcon # Valcon" == "Value Constructor" -- "FOO' in "Foo = FOO".
=
VALCON { # The first three fields are the only ones that really matter:
name: sy::Symbol, # Name of valcon -- "FOO" value-symbol.
type: Type,
form: vh::Valcon_Form, # Runtime form for valcon -- can be tagged_int or exception or all sorts of other stuff.
#
is_constant: Bool, # TRUE iff constructor takes no arguments -- e.g., TRUE, FALSE, NULL. (This field is redundant, could be determined from type.)
signature: vh::Valcon_Signature, # (Redundant, could be determined from type.)
#
is_lazy: Bool # Does valcon belong to lazy datatype? (Nonstandard, undocumented extension.)
};
}; # package types
end; # stipulate