


## 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 (fn (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 BUGGO 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::Uniqtype ), Loop_Kind)) # Is it recursive?
};
Typefun_Notes
=
{ inlining_hint: Inlining_Hint
};
# Classifying various kinds of records
#
Record_Kind
= RK_VECTOR hut::Uniqtyp # All elements have same type.
| RK_PACKAGE # Elements may be typeagnostic.
| RK_TUPLE hut::Useless_Recordflag # All fields are typelocked.
;
# dcon records the name of the constructor (for debugging),
# the corresponding Valcon_Form, and the highcode type hct::Uniqtype
# (which must be an arrow type). The use of Valcon_Form will go away soon. # XXX BUGGO FIXME
#
Dcon = (sy::Symbol, vh::Valcon_Form, hut::Uniqtype);
# 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 (Dcon, List(hut::Uniqtyp), 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::Uniqtyp)) # Apply type function Value to args List(hut::Uniqtyp).
| 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 (Dcon, List(hut::Uniqtyp), Value, tmp::Codetemp, Expression) # Bind tmp::Codetemp to Dcon(Value) over the scope of Expression. (We use List(hut::Uniqtyp) if Dcon 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::Uniqtype)) # Raise exception Value; give expression type List(hut::Uniqtype). (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::Uniqtype) ), # 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::Uniqtyp), tmp::Codetemp))
}
also
Baseop = (Null_Or(Dictionary), hbo::Baseop, hut::Uniqtype, List(hut::Uniqtyp));
# Invariant: baseop's hct::Uniqtype is always fully closed
}; # api Anormcode
end; # stipulate
## COPYRIGHT (c) 1997 YALE FLINT PROJECT
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2012,
## released under Gnu Public Licence version 3.


