aboutsummaryrefslogtreecommitdiff
path: root/frontend/parse.icl
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/parse.icl')
-rw-r--r--frontend/parse.icl338
1 files changed, 297 insertions, 41 deletions
diff --git a/frontend/parse.icl b/frontend/parse.icl
index f028ea0..c9471ed 100644
--- a/frontend/parse.icl
+++ b/frontend/parse.icl
@@ -1,7 +1,7 @@
implementation module parse
import StdEnv
-import scanner, syntax, hashtable, utilities, predef, containers
+import scanner, syntax, hashtable, utilities, predef, containers, genericsupport
ParseOnly :== False
@@ -567,61 +567,70 @@ where
wantGenericFunctionDefinition name pos pState
//# (type, pState) = wantType pState
# (ok, {at_type=type}, pState) = trySimpleType TA_None pState
- # (ident, pState) = stringToIdent name (IC_GenericCase type) pState
- # (type_CONS_ident, pState) = stringToIdent "CONS" IC_Type pState
- # (type_RECORD_ident, pState) = stringToIdent "RECORD" IC_Type pState
- # (type_FIELD_ident, pState)= stringToIdent "FIELD" IC_Type pState
- # (type_OBJECT_ident, pState)= stringToIdent "OBJECT" IC_Type pState
- # (generic_ident, pState) = stringToIdent name IC_Generic pState
-
- # (type_cons, pState) = get_type_cons type pState
+ # (ident, pState) = stringToIdent name (IC_GenericCase type) pState
+ # (generic_ident, pState) = stringToIdent name IC_Generic pState
+ # (type_cons, generic_fun_ident, pState) = get_type_cons type pState
with
get_type_cons (TA type_symb []) pState
- = (TypeConsSymb type_symb, pState)
+ = make_generic_fun_ident (TypeConsSymb type_symb) pState
get_type_cons (TA type_symb _) pState
# pState = parseError "generic type, no constructor arguments allowed" No " |}" pState
- = (abort "no TypeCons", pState)
- get_type_cons (TB tb) pState
- = (TypeConsBasic tb, pState)
+ = (abort_no_TypeCons, abort_no_TypeCons, pState)
+ get_type_cons (TB tb) pState
+ = make_generic_fun_ident (TypeConsBasic tb) pState
get_type_cons TArrow pState
- = (TypeConsArrow, pState)
+ = make_generic_fun_ident TypeConsArrow pState
get_type_cons (TV tv) pState
- = (TypeConsVar tv, pState)
+ = make_generic_fun_ident (TypeConsVar tv) pState
get_type_cons _ pState
# pState = parseError "generic type" No " |}" pState
- = (abort "no TypeCons", pState)
-
+ = (abort_no_TypeCons, abort_no_TypeCons, pState)
+
+ make_generic_fun_ident type_cons pState
+ # generic_fun_ident = genericIdentToFunIdent name type_cons
+ (generic_fun_ident,pState) = stringToIdent generic_fun_ident.id_name IC_Expression pState
+ = (type_cons, generic_fun_ident, pState)
+
# (token, pState) = nextToken GenericContext pState
- # (geninfo_arg, pState) = case token of
+ # (geninfo_arg, gcf_generic_info, pState) = case token of
GenericOfToken
# (ok, geninfo_arg, pState) = trySimplePattern pState
# pState = wantToken FunctionContext "type argument" GenericCloseToken pState
| ok
-> case type_cons of
- (TypeConsSymb {type_ident})
- | type_ident == type_CONS_ident
- -> (geninfo_arg, pState)
- | type_ident == type_RECORD_ident
- -> (geninfo_arg, pState)
- | type_ident == type_FIELD_ident
- -> (geninfo_arg, pState)
- | type_ident == type_OBJECT_ident
- -> (geninfo_arg, pState)
+ TypeConsSymb {type_ident=type_ident=:{id_name}}
+ | id_name=="OBJECT"
+ # (generic_constructor_type_ident, pState) = stringToIdent id_name IC_Type pState
+ | type_ident==generic_constructor_type_ident
+ -> (geninfo_arg, generic_info_of_OBJECT_geninfo_arg geninfo_arg, pState)
+ -> (geninfo_arg, 0, pState)
+ | id_name=="CONS"
+ # (generic_constructor_type_ident, pState) = stringToIdent id_name IC_Type pState
+ | type_ident==generic_constructor_type_ident
+ -> (geninfo_arg, generic_info_of_CONS_geninfo_arg geninfo_arg, pState)
+ -> (geninfo_arg, 0, pState)
+ | id_name=="RECORD"
+ # (generic_constructor_type_ident, pState) = stringToIdent id_name IC_Type pState
+ | type_ident==generic_constructor_type_ident
+ -> (geninfo_arg, generic_info_of_RECORD_geninfo_arg geninfo_arg, pState)
+ -> (geninfo_arg, 0, pState)
+ | id_name=="FIELD"
+ # (generic_constructor_type_ident, pState) = stringToIdent id_name IC_Type pState
+ | type_ident==generic_constructor_type_ident
+ -> (geninfo_arg, generic_info_of_FIELD_geninfo_arg geninfo_arg, pState)
+ -> (geninfo_arg, 0, pState)
_
- | otherwise
- -> (geninfo_arg, pState)
+ -> (geninfo_arg, 0, pState)
| otherwise
# pState = parseError "generic case" No "simple lhs expression" pState
- -> (PE_Empty, pState)
-
+ -> (PE_Empty, 0, pState)
+
GenericCloseToken
- # (geninfo_ident, pState) = stringToIdent "geninfo" IC_Expression pState
- -> (PE_Ident geninfo_ident, pState)
+ -> (PE_WildCard, 0, pState)
_
# pState = parseError "generic type" (Yes token) "of or |}" pState
- # (geninfo_ident, pState) = stringToIdent "geninfo" IC_Expression pState
- -> (PE_Ident geninfo_ident, pState)
-
+ -> (PE_WildCard, 0, pState)
+
//# pState = wantToken FunctionContext "type argument" GenericCloseToken pState
# (args, pState) = parseList trySimplePattern pState
# args = [geninfo_arg : args]
@@ -643,10 +652,14 @@ where
gcf_gident = generic_ident,
gcf_generic = {gi_module=NoIndex,gi_index=NoIndex},
gcf_arity = length args,
+ gcf_generic_info = gcf_generic_info,
gcf_body = GCB_ParsedBody args rhs,
- gcf_kind = KindError }
+ gcf_kind = KindError,
+ gcf_generic_instance_deps = AllGenericInstanceDependencies }
}
- = (True, PD_GenericCase generic_case, pState)
+ = (True, PD_GenericCase generic_case generic_fun_ident, pState)
+
+ abort_no_TypeCons => abort "no TypeCons"
wantForeignExportDefinition pState
# (token, pState) = nextToken GeneralContext pState
@@ -684,6 +697,74 @@ where
foreign_export_error s pState
= (True,PD_Erroneous,tokenBack (parseError "foreign export" No s pState))
+generic_info_of_RECORD_geninfo_arg (PE_Record PE_Empty NoRecordName field_assignments)
+ = mark_GenericRecordDescriptor_fields field_assignments 0
+ where
+ mark_GenericRecordDescriptor_fields :: [FieldAssignment] !Int -> Int
+ mark_GenericRecordDescriptor_fields [{bind_dst=FieldName {id_name}}:field_assignments] generic_info
+ # field_number=field_n_of_GenericRecordDescriptor id_name
+ | field_number>=0 && generic_info bitand (1<<field_number)==0
+ # generic_info = generic_info bitor (1<<field_number)
+ = mark_GenericRecordDescriptor_fields field_assignments generic_info
+ = -1
+ mark_GenericRecordDescriptor_fields [_:_] generic_info
+ = -1
+ mark_GenericRecordDescriptor_fields [] generic_info
+ = generic_info
+generic_info_of_RECORD_geninfo_arg _
+ = -1
+
+generic_info_of_OBJECT_geninfo_arg (PE_Record PE_Empty NoRecordName field_assignments)
+ = mark_GenericTypeDefDescriptor_fields field_assignments 0
+ where
+ mark_GenericTypeDefDescriptor_fields :: [FieldAssignment] !Int -> Int
+ mark_GenericTypeDefDescriptor_fields [{bind_dst=FieldName {id_name}}:field_assignments] generic_info
+ # field_number=field_n_of_GenericTypeDefDescriptor id_name
+ | field_number>=0 && generic_info bitand (1<<field_number)==0
+ # generic_info = generic_info bitor (1<<field_number)
+ = mark_GenericTypeDefDescriptor_fields field_assignments generic_info
+ = -1
+ mark_GenericTypeDefDescriptor_fields [_:_] generic_info
+ = -1
+ mark_GenericTypeDefDescriptor_fields [] generic_info
+ = generic_info
+generic_info_of_OBJECT_geninfo_arg _
+ = -1
+
+generic_info_of_CONS_geninfo_arg (PE_Record PE_Empty NoRecordName field_assignments)
+ = mark_GenericConsDescriptor_fields field_assignments 0
+ where
+ mark_GenericConsDescriptor_fields :: [FieldAssignment] !Int -> Int
+ mark_GenericConsDescriptor_fields [{bind_dst=FieldName {id_name}}:field_assignments] generic_info
+ # field_number=field_n_of_GenericConsDescriptor id_name
+ | field_number>=0 && generic_info bitand (1<<field_number)==0
+ # generic_info = generic_info bitor (1<<field_number)
+ = mark_GenericConsDescriptor_fields field_assignments generic_info
+ = -1
+ mark_GenericConsDescriptor_fields [_:_] generic_info
+ = -1
+ mark_GenericConsDescriptor_fields [] generic_info
+ = generic_info
+generic_info_of_CONS_geninfo_arg _
+ = -1
+
+generic_info_of_FIELD_geninfo_arg (PE_Record PE_Empty NoRecordName field_assignments)
+ = mark_GenericFieldDescriptor_fields field_assignments 0
+ where
+ mark_GenericFieldDescriptor_fields :: [FieldAssignment] !Int -> Int
+ mark_GenericFieldDescriptor_fields [{bind_dst=FieldName {id_name}}:field_assignments] generic_info
+ # field_number=field_n_of_GenericFieldDescriptor id_name
+ | field_number>=0 && generic_info bitand (1<<field_number)==0
+ # generic_info = generic_info bitor (1<<field_number)
+ = mark_GenericFieldDescriptor_fields field_assignments generic_info
+ = -1
+ mark_GenericFieldDescriptor_fields [_:_] generic_info
+ = -1
+ mark_GenericFieldDescriptor_fields [] generic_info
+ = generic_info
+generic_info_of_FIELD_geninfo_arg _
+ = -1
+
want_instance_type_definitions :: ![Type] !ParseState -> (![ParsedDefinition], !ParseState)
want_instance_type_definitions instance_type pState
= parseList want_instance_type_definition pState
@@ -1669,7 +1750,7 @@ wantGenericDefinition parseContext pos pState
# (ident, pState) = stringToIdent name IC_Generic/*IC_Class*/ pState
# (member_ident, pState) = stringToIdent name IC_Expression pState
# (arg_vars, pState) = wantList "generic variable(s)" try_variable pState
-
+ # (gen_deps, pState) = optionalDependencies pState
# pState = wantToken TypeContext "generic definition" DoubleColonToken pState
# (type, pState) = wantSymbolType pState
# pState = wantEndOfDefinition "generic definition" pState
@@ -1678,6 +1759,7 @@ wantGenericDefinition parseContext pos pState
, gen_member_ident = member_ident
, gen_type = type
, gen_vars = arg_vars
+ , gen_deps = gen_deps
, gen_pos = pos
, gen_info_ptr = nilPtr
}
@@ -1693,6 +1775,32 @@ wantGenericDefinition parseContext pos pState
# (token, pState) = nextToken TypeContext pState
= tryTypeVarT token pState
+ optionalDependencies :: !ParseState -> (![GenericDependency], !ParseState)
+ optionalDependencies pState
+ # (token, pState) = nextToken TypeContext pState
+ = case token of
+ BarToken -> wantSepList "generic dependencies" CommaToken TypeContext wantDependency pState
+ _ -> ([], tokenBack pState)
+
+ wantDependency :: !ParseState -> (Bool, GenericDependency, ParseState)
+ wantDependency pState
+ # (ident, pState) = wantIdentOrQualifiedIdent pState
+ # (vars, pState) = wantList "generic dependency variable(s)" try_variable pState
+ = (True, {gd_ident = ident, gd_index = NoGlobalIndex, gd_vars = vars, gd_nums = repeatn (length vars) (-1)}, pState)
+
+ wantIdentOrQualifiedIdent pState
+ # (token, pState) = nextToken TypeContext pState
+ = case token of
+ IdentToken name
+ # (ident, pState) = stringToIdent name IC_Generic pState
+ = (Ident ident, pState)
+ QualifiedIdentToken mod_name name
+ # (mod_ident, pState) = stringToQualifiedModuleIdent mod_name name IC_Generic pState
+ = (QualifiedIdent mod_ident name, pState)
+ _
+ # (ident, pState) = stringToIdent "" IC_Generic pState
+ = (Ident ident, parseError "generic dependency" (Yes token) "<identifier>" pState)
+
wantDeriveDefinition :: !ParseContext !Position !*ParseState -> (!ParsedDefinition, !*ParseState)
wantDeriveDefinition parseContext pos pState
| pState.ps_flags bitand PS_SupportGenericsMask==0
@@ -1733,12 +1841,50 @@ where
# (generic_ident, pState) = stringToIdent name IC_Generic pState
# (type_cons, pState) = get_type_cons type pState
# (token, pState) = nextToken GenericContext pState
+ # (gcf_generic_info, generic_instance_deps, token, pState)
+ = case token of
+ // make sure no look ahead occurred in a non GenericContext (defines an offside)
+ GenericOfToken
+ -> case type_cons of
+ TypeConsSymb {type_ident={id_name}}
+ | id_name=="OBJECT" || id_name=="CONS" || id_name=="RECORD" || id_name=="FIELD"
+ # (next_token, pState) = nextToken FunctionContext pState
+ -> case next_token of
+ IdentToken name
+ | isLowerCaseName name
+ # (token, pState) = nextToken GenericContext pState
+ # (generic_instance_deps, token, pState) = parse_optional_generic_instance_deps token pState
+ -> (-1, generic_instance_deps, token, pState)
+ CurlyOpenToken
+ # (token, pState) = nextToken FunctionContext pState
+ -> case token of
+ CurlyCloseToken
+ # (token, pState) = nextToken GenericContext pState
+ # (generic_instance_deps, token, pState) = parse_optional_generic_instance_deps token pState
+ -> (0, generic_instance_deps, token, pState)
+ _
+ # (generic_info,pState) = parse_info_fields id_name token pState
+ (token, pState) = nextToken GenericContext pState
+ # (generic_instance_deps, token, pState) = parse_optional_generic_instance_deps token pState
+ -> (generic_info,generic_instance_deps, token,pState)
+ _
+ # pState = parseError "derive definition" (Yes next_token) "{ or lower case ident" pState
+ -> (0, AllGenericInstanceDependencies, token, pState)
+ _
+ -> (0, AllGenericInstanceDependencies, token, pState)
+ GenericWithToken
+ # (generic_instance_deps, token, pState) = parse_generic_instance_deps 0 0 pState
+ -> (0, generic_instance_deps, token, pState)
+ _
+ -> (0, AllGenericInstanceDependencies, token, pState)
+
# derive_def =
{ gc_pos = pos
, gc_type = type
, gc_type_cons = type_cons
, gc_gcf = GCF ident {gcf_gident = generic_ident, gcf_generic = {gi_module=NoIndex,gi_index=NoIndex}, gcf_arity = 0,
- gcf_body = GCB_None, gcf_kind = KindError}
+ gcf_generic_info = gcf_generic_info, gcf_body = GCB_None, gcf_kind = KindError,
+ gcf_generic_instance_deps = generic_instance_deps}
}
= (derive_def, token, pState)
@@ -1757,7 +1903,8 @@ where
# (type, pState) = wantType pState
# (ident, pState) = stringToIdent class_ident.id_name (IC_GenericDeriveClass type) pState
# (type_cons, pState) = get_type_cons type pState
- # derive_def = { gc_pos = pos, gc_type = type, gc_type_cons = type_cons, gc_gcf = GCFC ident class_ident}
+ # derive_def = { gc_pos = pos, gc_type = type, gc_type_cons = type_cons,
+ gc_gcf = GCFC ident class_ident}
= (derive_def, pState)
get_type_cons :: Type !*ParseState -> (TypeCons, !*ParseState)
@@ -1774,6 +1921,115 @@ where
# pState = parseError "generic type" No " type constructor" pState
= (abort "no TypeCons", pState)
+ parse_info_fields "OBJECT" token pState
+ = parse_OBJECT_info_fields token 0 pState
+ parse_info_fields "CONS" token pState
+ = parse_CONS_info_fields token 0 pState
+ parse_info_fields "RECORD" token pState
+ = parse_RECORD_info_fields token 0 pState
+ parse_info_fields "FIELD" token pState
+ = parse_FIELD_info_fields token 0 pState
+
+ parse_OBJECT_info_fields token=:(IdentToken name) generic_info pState
+ # field_number=field_n_of_GenericTypeDefDescriptor name
+ | field_number<0
+ = (generic_info, parseError "GenericTypeDefDescriptor" (Yes token) "field of GenericTypeDefDescriptor" pState)
+ # field_mask = 1<<field_number
+ pState = if (generic_info bitand field_mask<>0)
+ (parseErrorSimple "GenericTypeDefDescriptor" "field already defined" pState)
+ pState
+ generic_info = generic_info bitor field_mask
+ (token, pState) = nextToken FunctionContext pState
+ = case token of
+ CommaToken
+ # (token,pState) = nextToken FunctionContext pState
+ -> parse_OBJECT_info_fields token generic_info pState
+ CurlyCloseToken
+ -> (generic_info,pState)
+ _
+ -> (generic_info, parseError "GenericTypeDefDescriptor record" (Yes token) ", or }" pState)
+ parse_OBJECT_info_fields token generic_info pState
+ = (generic_info, parseError "GenericTypeDefDescriptor record" (Yes token) "field name" pState)
+
+ parse_CONS_info_fields token=:(IdentToken name) generic_info pState
+ # field_number=field_n_of_GenericConsDescriptor name
+ | field_number<0
+ = (generic_info, parseError "GenericConsDescriptor" (Yes token) "field of GenericConsDescriptor" pState)
+ # field_mask = 1<<field_number
+ pState = if (generic_info bitand field_mask<>0)
+ (parseErrorSimple "GenericConsDescriptor" "field already defined" pState)
+ pState
+ generic_info = generic_info bitor field_mask
+ (token, pState) = nextToken FunctionContext pState
+ = case token of
+ CommaToken
+ # (token,pState) = nextToken FunctionContext pState
+ -> parse_CONS_info_fields token generic_info pState
+ CurlyCloseToken
+ -> (generic_info,pState)
+ _
+ -> (generic_info, parseError "GenericConsDescriptor record" (Yes token) ", or }" pState)
+ parse_CONS_info_fields token generic_info pState
+ = (generic_info, parseError "GenericConsDescriptor record" (Yes token) "field name" pState)
+
+ parse_RECORD_info_fields token=:(IdentToken name) generic_info pState
+ # field_number=field_n_of_GenericRecordDescriptor name
+ | field_number<0
+ = (generic_info, parseError "GenericRecordDescriptor" (Yes token) "field of GenericRecordDescriptor" pState)
+ # field_mask = 1<<field_number
+ pState = if (generic_info bitand field_mask<>0)
+ (parseErrorSimple "GenericRecordDescriptor" "field already defined" pState)
+ pState
+ generic_info = generic_info bitor field_mask
+ (token, pState) = nextToken FunctionContext pState
+ = case token of
+ CommaToken
+ # (token,pState) = nextToken FunctionContext pState
+ -> parse_RECORD_info_fields token generic_info pState
+ CurlyCloseToken
+ -> (generic_info,pState)
+ _
+ -> (generic_info, parseError "GenericRecordDescriptor record" (Yes token) ", or }" pState)
+ parse_RECORD_info_fields token generic_info pState
+ = (generic_info, parseError "GenericRecordDescriptor record" (Yes token) "field name" pState)
+
+ parse_FIELD_info_fields token=:(IdentToken name) generic_info pState
+ # field_number=field_n_of_GenericFieldDescriptor name
+ | field_number<0
+ = (generic_info, parseError "GenericFieldDescriptor" (Yes token) "field of GenericFieldDescriptor" pState)
+ # field_mask = 1<<field_number
+ pState = if (generic_info bitand field_mask<>0)
+ (parseErrorSimple "GenericFieldDescriptor" "field already defined" pState)
+ pState
+ generic_info = generic_info bitor field_mask
+ (token, pState) = nextToken FunctionContext pState
+ = case token of
+ CommaToken
+ # (token,pState) = nextToken FunctionContext pState
+ -> parse_FIELD_info_fields token generic_info pState
+ CurlyCloseToken
+ -> (generic_info,pState)
+ _
+ -> (generic_info, parseError "GenericFieldDescriptor record" (Yes token) ", or }" pState)
+ parse_FIELD_info_fields token generic_info pState
+ = (generic_info, parseError "GenericFieldDescriptor record" (Yes token) "field name" pState)
+
+ parse_optional_generic_instance_deps GenericWithToken pState
+ = parse_generic_instance_deps 0 0 pState
+ parse_optional_generic_instance_deps token pState
+ = (AllGenericInstanceDependencies, token, pState)
+
+ parse_generic_instance_deps n_deps deps pState
+ # (token, pState) = nextToken GenericContext pState
+ = case token of
+ WildCardToken
+ -> parse_generic_instance_deps (n_deps+1) deps pState
+ IdentToken name
+ | isLowerCaseName name
+ -> parse_generic_instance_deps (n_deps+1) (deps bitor (1<<n_deps)) pState
+ _
+ -> (GenericInstanceDependencies n_deps deps, token, pState)
+
/*
Type definitions
*/