## anormcode-form.pkg
#
# "A-Normal" intermediate code form.
# See extensive comments in
src/lib/compiler/back/top/anormcode/anormcode-form.api# Compiled by:
#
src/lib/compiler/core.sublib### "See, commas and semis and braces -- that's
### not what a compiler *is*.
### That's what a compiler *needs*.
### What a compiler *is* -- is freedom!"
###
### -- Hacker Jack Sparrow.
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; # Should go away soon
herein
package anormcode_form
: (weak) Anormcode_Form # Anormcode_Form is from
src/lib/compiler/back/top/anormcode/anormcode-form.api {
# What kind of inlining behavior
# is desired for the function?
#
Inlining_Hint
= INLINE_IF_SIZE_SAFE # Only if trivially size-safe.
| INLINE_WHENEVER_POSSIBLE
# Inline whenever possible.
| INLINE_ONCE_WITHIN_ITSELF
# Only inline 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?
#
Loop_Kind
= OTHER_LOOP # something else
| PREHEADER_WRAPPED_LOOP
# loop wrapped in a preheader
| TAIL_RECURSIVE_LOOP
# properly 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 should it 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
# Package -- elements may be typeagnostic.
| RK_TUPLE hut::Useless_Recordflag
# All elements are typelocked.
;
# Valcon records the name of the constructor (for debugging),
# the corresponding sumtypeConstructorRepresentation,
# and the highcode type hct::Uniqtypoid (which must be an arrow type).
#
Valcon
=
( sy::Symbol,
vh::Valcon_Form,
hut::Uniqtypoid
);
# Case constants 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 shorthand 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 InfInf::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;
# 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)
| MUTUALLY_RECURSIVE_FNS (List( Function ), Expression)
| APPLY (Value, List( Value ))
| TYPEFUN (Typefun, Expression)
| APPLY_TYPEFUN (Value, List( hut::Uniqtype ))
| SWITCH (Value, vh::Valcon_Signature, List( (Casetag, Expression) ), Null_Or(Expression))
| CONSTRUCTOR (Valcon, List( hut::Uniqtype ), Value, tmp::Codetemp, Expression)
| RECORD (Record_Kind, List(Value), tmp::Codetemp, Expression)
| GET_FIELD (Value, Int, tmp::Codetemp, Expression)
| RAISE (Value, List( hut::Uniqtypoid ))
| EXCEPT (Expression, Value)
| BRANCH (Baseop, List( Value ), Expression, Expression)
| BASEOP (Baseop, List( Value ), tmp::Codetemp , 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
}; # package anormcode
end; # stipulate