## anormcode-form.api
#
# For background see:
#
# src/AN.A-NORMAL-FORM.OVERVIEW
#
# Compiled by:
#
src/lib/compiler/core.sublib### "Wisdom begins in wonder."
###
### -- Socrates (circa 470-399BC)
stipulate
package hbo = highcode_baseops; # highcode_baseops is from
src/lib/compiler/back/top/highcode/highcode-baseops.pkg package hct = highcode_type; # highcode_type is from
src/lib/compiler/back/top/highcode/highcode-type.pkg package tmp = highcode_codetemp; # highcode_codetemp is from
src/lib/compiler/back/top/highcode/highcode-codetemp.pkg package hut = highcode_uniq_types; # highcode_uniq_types is from
src/lib/compiler/back/top/highcode/highcode-uniq-types.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
api Anormcode_Form {
#
# What kind of inlining behavior
# is desired for the function:
#
Inlining_Hint
= INLINE_IF_SIZE_SAFE # Inline only if trivially size-safe.
| INLINE_WHENEVER_POSSIBLE
# Inline whenever possible.
| INLINE_ONCE_WITHIN_ITSELF
# Inline only once within itself.
| INLINE_MAYBE (Int, List( Int ))
# Call-site dependent inlining:
; # #1 < sum (map2 (\\ (a, w) = (known a) * w) (actuals, #2)
# What kind of recursive function (aka loop) is this
# the distinction between PREHEADER_WRAPPED_LOOP and OTHER_LOOP is not clear
# and might get dropped so that we only need `tail: Bool' XXX QUERO FIXME
#
Loop_Kind
= OTHER_LOOP # something else
| PREHEADER_WRAPPED_LOOP
# loop wrapped in a preheader
| TAIL_RECURSIVE_LOOP
# like PREHEADER_WRAPPED_LOOP but tail-recursive
;
Call_As
= CALL_AS_GENERIC_PACKAGE # It is a generic package.
| CALL_AS_FUNCTION hut::Calling_Convention
# It is a function.
;
Function_Notes
=
{ inlining_hint: Inlining_Hint, # When it should be inlined?
private: Bool, # Are all the call sites known?
call_as: Call_As, # Calling convention: function vs generic package.
loop_info: Null_Or( (List( hut::Uniqtypoid ), Loop_Kind)) # Is it recursive?
};
Typefun_Notes
=
{ inlining_hint: Inlining_Hint
};
# Classifying various kinds of records
#
Record_Kind
= RK_VECTOR hut::Uniqtype # All elements have same type.
| RK_PACKAGE
# Elements may be typeagnostic.
| RK_TUPLE hut::Useless_Recordflag
# All fields are typelocked.
;
# valcon records the name of the constructor (for debugging),
# the corresponding Valcon_Form, and the highcode type hct::Uniqtypoid
# (which must be an arrow type). The use of Valcon_Form will go away soon. # XXX BUGGO FIXME
#
Valcon = (sy::Symbol, vh::Valcon_Form, hut::Uniqtypoid);
# Casetag: Used to specify all possible switching statements.
# Efficient switch generation can be applied to VAL_CASETAG and INT_CASETAG.
# Otherwise, the switch is just a short-hand for a binary search tree.
# Some of these instances such as FLOAT64_CASETAG and VLEN_CASETAG will go away soon. XXX BUGGO FIXME
#
Casetag # Constant in a 'case' rule lefthandside.
= VAL_CASETAG (Valcon, List(hut::Uniqtype), tmp::Codetemp)
| INT_CASETAG Int
# should use multiword_int::Int XXX BUGGO FIXME
| INT1_CASETAG one_word_int::Int
| UNT_CASETAG Unt
| UNT1_CASETAG one_word_unt::Unt
| FLOAT64_CASETAG String
| STRING_CASETAG String
| VLEN_CASETAG Int
;
# Define our simple values, including
# variables and static constants:
#
Value
= VAR tmp::Codetemp
| INT Int
# Should use multiword_int::Int. XXX BUGGO FIXME.
| INT1 one_word_int::Int
| UNT Unt
| UNT1 one_word_unt::Unt
| FLOAT64 String
| STRING String
;
Expression
#
= RET List( Value )
| LET (List(tmp::Codetemp), Expression, Expression)
# Define Variable as Expression1 over the scope of Expression2.
| MUTUALLY_RECURSIVE_FNS (List(Function), Expression)
# Define the given Functions over the scope of Expression.
| APPLY (Value, List(Value))
# Apply function Value to args List(Value).
| TYPEFUN (Typefun, Expression)
# Define the given Typefun over the scope of Expression.
| APPLY_TYPEFUN (Value, List(hut::Uniqtype))
# Apply type function Value to args List(hut::Uniqtype).
| SWITCH (Value, vh::Valcon_Signature, List( (Casetag, Expression) ), Null_Or(Expression))
# Evaluate the Expression whose Casetag matches Value; if none match do the Null_Or(Expression).
| CONSTRUCTOR (Valcon, List(hut::Uniqtype), Value, tmp::Codetemp, Expression)
# Bind tmp::Codetemp to Valcon(Value) over the scope of Expression. (We use List(hut::Uniqtype) if Valcon is typeagnostic.)
| RECORD (Record_Kind, List(Value), tmp::Codetemp, Expression)
# Tuple construction: Bind tmp::Codetemp to Record_Kind (List(Value) ) over the scope of Expression.
| GET_FIELD (Value, Int, tmp::Codetemp, Expression)
# Tuple field selection: Bind tmp::Codetemp to Value[Int] over the scope of Expression.
| RAISE (Value, List(hut::Uniqtypoid))
# Raise exception Value; give expression type List(hut::Uniqtypoid). (Need explicit type since it doesn't return.)
| EXCEPT (Expression, Value)
# Evaluate Expression with Value as the exception handler.
| BRANCH (Baseop, List(Value), Expression, Expression)
# If Baseop( List(Value) ) evaluate Expression1 else Expression2.
| BASEOP (Baseop, List(Value), tmp::Codetemp, Expression)
# Arithmetic etc: Bind tmp::Codetemp to Baseop( List(Value) ) over the scope of Expression.
withtype
Function
=
( Function_Notes,
tmp::Codetemp,
List( (tmp::Codetemp, hut::Uniqtypoid) ), # Our args are values, so our parameters have types.
Expression
)
also
Typefun
=
( Typefun_Notes,
tmp::Codetemp,
List( (tmp::Codetemp, hut::Uniqkind) ), # Our args are types, so our parameters have kinds.
Expression
)
also
Dictionary = { default: tmp::Codetemp,
table: List( (List(hut::Uniqtype), tmp::Codetemp))
}
also
Baseop = (Null_Or(Dictionary), hbo::Baseop, hut::Uniqtypoid, List(hut::Uniqtype));
# Invariant: baseop's hct::Uniqtypoid is always fully closed
}; # api Anormcode
end; # stipulate
## COPYRIGHT (c) 1997 YALE FLINT PROJECT
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.