## deep-syntax.api
#
# Deep syntax. The typechecker accepts a raw syntax
# expression and returns a deep syntax expression:
#
#
src/lib/compiler/front/semantic/typecheck/translate-raw-syntax-to-deep-syntax.pkg#
# Raw syntax is defined in
#
src/lib/compiler/front/parser/raw-syntax/raw-syntax.api#
src/lib/compiler/front/parser/raw-syntax/raw-syntax.pkg#
# Deep syntax differs from raw syntax primarily in
# that (surprise) everything now has an associated
# type.
#
# Deep syntax, per se, is also much simpler, since
# much of the complexity of raw syntax relates to
# type declarations etc, which stuff is handed off to
#
src/lib/compiler/front/typer-stuff/types/type-declaration-types.api#
src/lib/compiler/front/typer-stuff/types/type-declaration-types.pkg#
src/lib/compiler/front/typer-stuff/modules/module-level-declarations.api#
src/lib/compiler/front/typer-stuff/modules/module-level-declarations.pkg# etc.
#
# Deep syntax gets translated into A-Normal form using
# a polymorphically typed lambda calculus as a stepping
# stone:
#
#
src/lib/compiler/back/top/lambdacode/lambdacode-form.api#
src/lib/compiler/back/top/anormcode/anormcode-form.api#
src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg#
# FUTURE WORK: I'm inclined to think all the mutable elements should
# be factored out of the deep syntax tree proper --
# see Note[1] in
src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax-junk.pkg# Compiled by:
#
src/lib/compiler/front/typer-stuff/typecheckdata.sublib### "One word in the wrong place
### ruins the most precious thought."
###
### -- Voltaire
stipulate
package fix = fixity; # fixity is from
src/lib/compiler/front/basics/map/fixity.pkg package int = multiword_int; # multiword_int is from
src/lib/std/multiword-int.pkg package mld = module_level_declarations; # module_level_declarations is from
src/lib/compiler/front/typer-stuff/modules/module-level-declarations.pkg package sp = symbol_path; # symbol_path is from
src/lib/compiler/front/typer-stuff/basics/symbol-path.pkg package sxe = symbolmapstack_entry; # symbolmapstack_entry is from
src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack-entry.pkg package sy = symbol; # symbol is from
src/lib/compiler/front/basics/map/symbol.pkg package tdt = type_declaration_types; # type_declaration_types is from
src/lib/compiler/front/typer-stuff/types/type-declaration-types.pkg package vac = variables_and_constructors; # variables_and_constructors is from
src/lib/compiler/front/typer-stuff/deep-syntax/variables-and-constructors.pkgherein
api Deep_Syntax {
#
#
Source_Code_Region; # Used for error messages, to identify the part of the sourcefile containing the erroneous code.
Numbered_Label # These name tuple fields; used only in RECORD_IN_EXPRESSION and RECORD_SELECTOR_EXPRESSION.
=
NUMBERED_LABEL { name: sy::Symbol,
number: Int
};
Deep_Expression
#
= VARIABLE_IN_EXPRESSION { var: Ref(vac::Variable), typescheme_args: List(tdt::Typoid) } # See Note[1].
| VALCON_IN_EXPRESSION { valcon: tdt::Valcon, typescheme_args: List(tdt::Typoid) }
# "valcon" == "value constructor", like THE. (As opposed to type constructors, like List().)
| INT_CONSTANT_IN_EXPRESSION (int::Int, tdt::Typoid)
| UNT_CONSTANT_IN_EXPRESSION (int::Int, tdt::Typoid)
| FLOAT_CONSTANT_IN_EXPRESSION String
| STRING_CONSTANT_IN_EXPRESSION String
| CHAR_CONSTANT_IN_EXPRESSION String
| RECORD_IN_EXPRESSION List ((Numbered_Label, Deep_Expression))
| RECORD_SELECTOR_EXPRESSION (Numbered_Label, Deep_Expression)
| VECTOR_IN_EXPRESSION (List( Deep_Expression ), tdt::Typoid)
| ABSTRACTION_PACKING_EXPRESSION (Deep_Expression, tdt::Typoid, List( tdt::Type ))
| APPLY_EXPRESSION { operator: Deep_Expression, operand: Deep_Expression }
| EXCEPT_EXPRESSION (Deep_Expression, Fnrules)
| RAISE_EXPRESSION (Deep_Expression, tdt::Typoid)
| CASE_EXPRESSION (Deep_Expression, List( Case_Rule ), Bool)
# TRUE: match (fun/fn); FALSE: bind (my (...)=...) This should be a separate sumtype for readability: Case_Context = DOING_MATCH
| DOING_BIND; XXX SUCKO FIXME.
| OR_EXPRESSION (Deep_Expression, Deep_Expression)
| AND_EXPRESSION (Deep_Expression, Deep_Expression)
| FN_EXPRESSION Fnrules
| SEQUENTIAL_EXPRESSIONS List( Deep_Expression )
| LET_EXPRESSION (Declaration, Deep_Expression)
| TYPE_CONSTRAINT_EXPRESSION (Deep_Expression, tdt::Typoid)
| WHILE_EXPRESSION { test: Deep_Expression,
expression: Deep_Expression
}
| IF_EXPRESSION { test_case: Deep_Expression,
then_case: Deep_Expression,
else_case: Deep_Expression
}
| SOURCE_CODE_REGION_FOR_EXPRESSION (Deep_Expression, Source_Code_Region)
also
Case_Rule
#
= CASE_RULE (Case_Pattern, Deep_Expression)
also
Case_Pattern
#
= WILDCARD_PATTERN
| NO_PATTERN
| TYPE_CONSTRAINT_PATTERN (Case_Pattern, tdt::Typoid)
| AS_PATTERN (Case_Pattern, Case_Pattern)
| OR_PATTERN (Case_Pattern, Case_Pattern)
| VARIABLE_IN_PATTERN vac::Variable
| INT_CONSTANT_IN_PATTERN (int::Int, tdt::Typoid)
| UNT_CONSTANT_IN_PATTERN (int::Int, tdt::Typoid)
| FLOAT_CONSTANT_IN_PATTERN String
| STRING_CONSTANT_IN_PATTERN String
| CHAR_CONSTANT_IN_PATTERN String
| CONSTRUCTOR_PATTERN (tdt::Valcon, List( tdt::Typoid ))
| APPLY_PATTERN (tdt::Valcon, List( tdt::Typoid ), Case_Pattern)
| VECTOR_PATTERN (List( Case_Pattern ), tdt::Typoid)
| RECORD_PATTERN { fields: List( (tdt::Label, Case_Pattern)),
is_incomplete: Bool,
type_ref: Ref( tdt::Typoid )
}
also
Declaration
#
= EXCEPTION_DECLARATIONS List( Named_Exception )
| RECURSIVE_VALUE_DECLARATIONS List( Named_Recursive_Value )
| VALUE_DECLARATIONS List( Named_Value )
| TYPE_DECLARATIONS List( tdt::Type )
| PACKAGE_DECLARATIONS List( Named_Package )
| GENERIC_DECLARATIONS List( Named_Generic )
| API_DECLARATIONS List( mld::Api )
| GENERIC_API_DECLARATIONS List( mld::Generic_Api )
| INCLUDE_DECLARATIONS List ((sp::Symbol_Path, mld::Package))
| LOCAL_DECLARATIONS (Declaration, Declaration)
| SEQUENTIAL_DECLARATIONS List( Declaration )
| OVERLOADED_VARIABLE_DECLARATION vac::Variable
| SUMTYPE_DECLARATIONS { sumtypes: List( tdt::Type ),
with_types: List( tdt::Type )
}
| FIXITY_DECLARATION { fixity: fix::Fixity,
ops: List( sy::Symbol )
}
| SOURCE_CODE_REGION_FOR_DECLARATION (Declaration, Source_Code_Region)
also
Package_Expression
#
= PACKAGE_BY_NAME mld::Package
| PACKAGE_DEFINITION List( sxe::Symbolmapstack_Entry )
| PACKAGE_LET { declaration: Declaration,
expression: Package_Expression
}
| COMPUTED_PACKAGE { a_generic: mld::Generic,
generic_argument: mld::Package,
parameter_types: List( tdt::Typepath )
}
| SOURCE_CODE_REGION_FOR_PACKAGE (Package_Expression, Source_Code_Region)
also
Generic_Expression
#
= GENERIC_BY_NAME mld::Generic
| GENERIC_LET (Declaration, Generic_Expression)
| GENERIC_DEFINITION { parameter: mld::Package,
parameter_types: List( tdt::Typepath ),
definition: Package_Expression
}
| SOURCE_CODE_REGION_FOR_GENERIC (Generic_Expression, Source_Code_Region)
also # Encodes a "foo = bar;" statement. This can be arbitrarily complex
Named_Value # like "my FOO { this, that => BAR (alpha, beta), ... } = somefn (ZOT { beta, gamma }, 13);"
# # or "swap = fn (x: X, y: Y) = (y,x);";
= VALUE_NAMING # Not called "NAMED_VALUE" because more than one value may acquire a name here.
{
pattern: Case_Pattern, # Left-hand side of the "... = ...".
expression: Deep_Expression, # Right-hand side of the "... = ...".
raw_typevars: Ref( List( tdt::Typevar_Ref ) ), # Raw list of X, Y ... user typevars found in statement.
generalized_typevars: List( tdt::Typevar_Ref ) # Subset of previous: the X, Y... which actually got generalized.
} #
# raw_typevars:
# List of explicit user type variabls X, Y, Z ...
# found in patterns in function arguments etc.
# This is the list of candidates for let-polymormphic
# type generalization. This gets used in
#
src/lib/compiler/front/typer/types/type-core-language-declaration-g.pkg # in generalize_pattern() (where it is called 'userbound') and
# in generalize_type() (where it is called 'user_typevar_refs').
#
# generalized_typevars:
# List of generalized type variables.
# This gets generated in
src/lib/compiler/front/typer/types/type-core-language-declaration-g.pkg # and later used in
src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg
also
Named_Recursive_Value # Encodes one of a set of mutually recursive values -- in practice, almost always mutuallly recursive functions, say
# # "fun foo () = bar () also fun bar () = foo ();"
= NAMED_RECURSIVE_VALUE
{ variable: vac::Variable, # Name for value.
expression: Deep_Expression, # Expression defining value.
raw_typevars: Ref( List( tdt::Typevar_Ref ) ), # Raw list of X, Y ... user typevars found in statement.
generalized_typevars: List( tdt::Typevar_Ref ), # Subset of previous: the X, Y... which actually got generalized.
null_or_type: Null_Or( tdt::Typoid )
}
# As in Named_Value, generalized_typevars gives a list of typevars
# being generalized at this binding. However, the mutually recursive
# list of recursive value bindings could share type variables, that is,
# the generalized_typevars sets used in these NAMED_RECURSIVE_VALUEs
# could contain overlapping sets of typevars.
also
Named_Exception
#
= NAMED_EXCEPTION { exception_constructor: tdt::Valcon,
exception_typoid: Null_Or( tdt::Typoid ),
name_string: Deep_Expression
}
| DUPLICATE_NAMED_EXCEPTION
{ exception_constructor: tdt::Valcon,
equal_to: tdt::Valcon
}
also
Named_Package
#
= NAMED_PACKAGE { name_symbol: sy::Symbol,
a_package: mld::Package,
definition: Package_Expression
}
also
Named_Generic
#
= NAMED_GENERIC { name_symbol: sy::Symbol,
a_generic: mld::Generic,
definition: Generic_Expression
}
withtype Fnrules = (List( Case_Rule ), tdt::Typoid);
}; # Api Deep_Syntax
end; # stipulate
################################################################################################################################
# Note[1]: = VARIABLE_IN_EXPRESSION { var: (Ref(vac::Variable), typescheme_args: List(tdt::Typoid) }
#
# Here 'var' is of most interest.
#
# The 'typescheme_args' value will be [] until we reach
#
#
src/lib/compiler/front/typer/types/type-core-language-declaration-g.pkg#
# At that point, if the type of 'var' is given by a typescheme,
# 'typescheme_args' will be set to list of types which must be
# plugged into the typescheme in order to produce the concrete
# type for the variable.
#
# (A typescheme is essentially a macro which expands into a type
# when supplied with appropriate types as arguments. This is
# the mechanism which allows list::length: List(X) -> Int to expand
# into type list::length: List(String) -> Int for one call and
# into type list::length: List(Float) -> Int for another call etc.)