#line 247 "/home/ubuntu/felix/src/packages/grammar.fdoc" syntax expressions { priority let_pri < slambda_pri < spipe_apply_pri < sdollar_apply_pri < // TUPLES stuple_cons_pri < stuple_pri < scompacttuple_pri < // LOGIC simplies_condition_pri < sor_condition_pri < sand_condition_pri < snot_condition_pri < // TEX LOGIC stex_implies_condition_pri < stex_or_condition_pri < stex_and_condition_pri < stex_not_condition_pri < // COMPARISONS scomparison_pri < sas_expr_pri < // SETWISE OPERATORS ssetunion_pri < ssetintersection_pri < sarrow_pri < scase_literal_pri < // BITWISE OPERATORS sbor_pri < sbxor_pri < sband_pri < sshift_pri < // NUMERIC OPERATORS ssum_pri < scompactsum_pri < ssubtraction_pri < sproduct_pri < scompactproduct_pri < s_term_pri < // division // STUFF sprefixed_pri < spower_pri < ssuperscript_pri < srefr_pri < scoercion_pri < // WHITESPACE APPLICATION sapplication_pri < sfactor_pri < srcompose_pri < sthename_pri < satomic_pri ; requires types, setexpr, cmpexpr, pordcmpexpr, tordcmpexpr, addexpr, mulexpr, divexpr, bitexpr, spipeexpr, boolexpr, stringexpr, listexpr, tupleexpr ; sexpr := x[let_pri] =># "_1"; //$ Let binding. x[let_pri] := "let" spattern "=" x[let_pri] "in" x[let_pri] =># "`(ast_letin ,_sr (,_2 ,_4 ,_6))"; //$ Let fun binding. x[let_pri] := "let" "fun" sdeclname sfun_arg* fun_return_type "=>" x[let_pri] "in" x[let_pri] =># """ (let* ( (body `((ast_fun_return ,_sr ,_7))) (fun_decl `(ast_curry_effects ,_sr ,(first _3) ,(second _3) ,_4 ,(first _5) ,(second _5) Function () ,body)) (final_return `(ast_fun_return ,_sr ,_9)) ) (block_expr `(,fun_decl ,final_return)) ) """; // FIXME x[let_pri] := "let" "fun" sdeclname fun_return_type "=" smatching+ "in" x[let_pri] =># """ (let* ( (ixname _3) (name (first ixname)) (tvars (second ixname)) (t (first (first _4))) (traint (second (first _4))) (matching _6) (expr _8) ) (if (eq? 'typ_arrow (first t)) (let* ( (argt (caadr t)) (ret (cadadr t)) (params `((((,_sr PVal _a ,argt none)) none))) ;; parameters (body `((ast_fun_return ,_sr (ast_match ,_sr (,(noi '_a) ,matching))))) (fun_decl `(ast_curry ,_sr ,name ,tvars ,params (,ret ,traint) Function () ,body) ) (final_return `(ast_fun_return ,_sr ,expr)) ) (block_expr `(,fun_decl ,final_return)) ) 'ERROR ) ) """; //$ Unterminated match x[let_pri] := "let" pattern_match =># "_2"; // below gets confused with statement expression .. :-) satom := "(" "var" sname "=" sexpr ")" =># "`(ast_as_var ,_sr (,_5 ,_3))"; satom := "(" "val" sname "=" sexpr ")" =># "`(ast_as ,_sr (,_5 ,_3))"; //$ Conditional expression. x[let_pri] := sconditional =># '_1'; //$ Pattern matching. x[let_pri] := pattern_match =># '_1'; //$ Low precedence right associative application. x[sdollar_apply_pri] := x[>sdollar_apply_pri] "$" x[sdollar_apply_pri] =># "`(ast_apply ,_sr (,_1 ,_3))"; //$ Low precedence left associative reverse application. x[spipe_apply_pri] := x[spipe_apply_pri] "|>" x[>spipe_apply_pri] =># "`(ast_apply ,_sr (,_3 ,_1))"; //$ Haskell-ish style infix notation of functions foo(x,y) => x `(foo) y x[stuple_pri] := x[stuple_pri] "`(" sexpr ")" sexpr =># "(binop _3 _1 _5)"; //$ Named temporary value. x[sas_expr_pri] := x[sas_expr_pri] "as" sname =># "`(ast_as ,_sr (,_1 ,_3))"; //$ Named variable. x[sas_expr_pri] := x[sas_expr_pri] "as" "var" sname =># "`(ast_as_var ,_sr (,_1 ,_4))"; x[sarrow_pri] := x[>sarrow_pri] ".." x[>sarrow_pri] =># "(infix 'Slice_range_incl)"; x[sarrow_pri] := x[>sarrow_pri] "..<" x[>sarrow_pri] =># "(infix 'Slice_range_excl)"; x[sarrow_pri] := "..<" x[>sarrow_pri] =># "(prefix 'Slice_to_excl)"; x[sarrow_pri] := ".." x[>sarrow_pri] =># "(prefix 'Slice_to_incl)"; x[sarrow_pri] := x[>sarrow_pri] ".." =># "(suffix 'Slice_from)"; x[sarrow_pri] := ".." =># """`(ast_name ,_sr "Slice_all" () )"""; x[sarrow_pri] := "..[" stypeexpr "]" =># """`(ast_type_slice ,_sr ,_2 )"""; x[sarrow_pri] := x[>sarrow_pri] ".+" x[>sarrow_pri] =># "(infix 'Slice_from_counted)"; x[scase_literal_pri] := "case" sinteger =># "`(ast_case_tag ,_sr ,_2))"; x[scase_literal_pri] := "`" sinteger =># "`(ast_case_tag ,_sr ,_2))"; //$ Case value. x[scase_literal_pri] := "case" sinteger "of" t[ssum_pri] =># "`(ast_unitsum_literal ,_sr ,_2 ,_4)"; x[scase_literal_pri] := "`" sinteger "of" t[ssum_pri] =># "`(ast_unitsum_literal ,_sr ,_2 ,_4)"; x[scase_literal_pri] := "`" sinteger ":" t[ssum_pri] =># "`(ast_unitsum_literal ,_sr ,_2 ,_4)"; //$ Tuple projection function. x[scase_literal_pri] := "proj" sinteger "of" t[ssum_pri] =># "`(ast_projection ,_sr ,_2 ,_4)"; x[scase_literal_pri] := "aproj" sexpr "of" t[ssum_pri] =># "`(ast_array_projection ,_sr ,_2 ,_4)"; x[scase_literal_pri] := "ident" "of" t[ssum_pri] =># "`(ast_identity_function ,_sr ,_3)"; // coarray injection // (ainj (r:>>4) of (4 *+ int)) 42 x[scase_literal_pri] := "ainj" stypeexpr "of" t[ssum_pri] =># "`(ast_ainj ,_sr ,_2 ,_4)"; spv_name := "case" sname =># "_2"; spv_name := "`" sname =># "_2"; //$ Variant value. x[sthename_pri] := "#" spv_name =># "`(ast_variant (,_2 ()))"; x[sapplication_pri] := spv_name x[>sapplication_pri] =># "`(ast_variant (,_1 ,_2))"; //$ multiplication: right associative x[sproduct_pri] := x[>sproduct_pri] "\otimes" x[sproduct_pri] =># "(Infix)"; // repeated sum type, eg 4 *+ int == int + int + int + int // right associative: 2 *+ 3 *+ int is approx 6 *+ int //x[sproduct_pri] := x[>sproduct_pri] "*+" x[sproduct_pri] =># "`(ast_rptsum_type ,_sr ,_1 ,_3)"; //------------------------------------------------------------------------ //$ Prefix exclaim. x[sprefixed_pri] := "!" x[sprefixed_pri] =># "(Prefix)"; //$ Prefix plus. x[sprefixed_pri] := "+" x[sprefixed_pri] =># "(prefix 'prefix_plus)"; //$ Prefix negation. x[sprefixed_pri] := "-" x[sprefixed_pri] =># "(prefix 'neg)"; //$ Prefix complement. x[sprefixed_pri] := "~" x[sprefixed_pri] =># "(Prefix)"; //$ Fortran power. x[spower_pri] := x[ssuperscript_pri] "**" x[sprefixed_pri] =># "(infix 'pow)"; x[spower_pri] := x[ssuperscript_pri] "<**>" x[sprefixed_pri] =># "(infix 'tuple_snoc)"; //$ Superscript, exponential. x[ssuperscript_pri] := x[ssuperscript_pri] "^" x[srefr_pri] =># "`(ast_superscript (,_1 ,_3))"; //$ composition x[ssuperscript_pri] := x[ssuperscript_pri] "\circ" x[>ssuperscript_pri] =># "(Infix)"; x[ssuperscript_pri] := x[ssuperscript_pri] "\cdot" x[>ssuperscript_pri] =># "(Infix)"; //------------------------------------------------------------------------ //$ C dereference. x[srefr_pri] := "*" x[srefr_pri] =># "(prefix 'deref)"; //$ Deref primitive. //x[srefr_pri] := "_deref" x[srefr_pri] =># "`(ast_deref ,_sr ,_2)"; //$ Operator new. x[srefr_pri] := "new" x[srefr_pri] =># "`(ast_new ,_sr ,_2)"; //------------------------------------------------------------------------ //$ Operator whitespace: application. x[sapplication_pri] := x[sapplication_pri] x[>sapplication_pri] =># "`(ast_apply ,_sr (,_1 ,_2))" note "apply"; //$ Variant index. x[sapplication_pri] := "caseno" x[>sapplication_pri] =># "`(ast_case_index ,_sr ,_2)"; x[sapplication_pri] := "casearg" x[>sapplication_pri] =># "`(ast_rptsum_arg ,_sr ,_2)"; //$ Optimisation hint: likely. //$ Use in conditionals, e.g. if likely(x) do ... x[sapplication_pri] := "likely" x[>sapplication_pri] =># "`(ast_likely ,_sr ,_2)"; //$ Optimisation hint: unlikely. //$ Use in conditionals, e.g. if unlikely(x) do ... x[sapplication_pri] := "unlikely" x[>sapplication_pri] =># "`(ast_unlikely ,_sr ,_2)"; //------------------------------------------------------------------------ //$ Suffixed coercion. x[slambda_pri] := x[>slambda_pri] ":>>" stypeexpr =># "`(ast_coercion ,_sr (,_1 ,_3))"; x[sfactor_pri] := ssuffixed_name =># "_1"; //------------------------------------------------------------------------ //$ Reverse application. x[sfactor_pri] := x[sfactor_pri] "." x[>sfactor_pri] =># "`(ast_apply ,_sr (,_3 ,_1))"; //$ Reverse application with dereference. //$ a *. b same as (*a) . b, like C a -> b. x[sfactor_pri] := x[sfactor_pri] "*." x[>sfactor_pri] =># "`(ast_apply ,_sr (,_3 (ast_apply ,_sr (,(noi 'deref) ,_1))))" ; x[sfactor_pri] := x[sfactor_pri] "->" x[>sfactor_pri] =># "`(ast_apply ,_sr (,_3 (ast_apply ,_sr (,(noi 'deref) ,_1))))" ; //$ a &. b is similar to &a . b for an array, but can be overloaded //$ for abstract arrays: like a + b in C. Returns pointer. // x[sfactor_pri] := x[sfactor_pri] "&." sthe_name =># "(Infix)"; x[sfactor_pri] := x[sfactor_pri] "&." x[>sfactor_pri] =># "`(ast_apply ,_sr (,_3 (ast_ref ,_sr ,_1)))"; //------------------------------------------------------------------------ //$ Reverse composition x[srcompose_pri] := x[srcompose_pri] "\odot" x[>srcompose_pri] =># "(Infix)"; //------------------------------------------------------------------------ //$ High precedence unit application. #f = f (). x[sthename_pri] := "#" x[sthename_pri] =># "`(ast_apply ,_sr (,_2 (ast_tuple ,_sr ())))"; //$ Felix pointer type and address of operator. x[sthename_pri] := "&" x[sthename_pri] =># "`(ast_ref ,_sr ,_2)"; //$ Felix pointer type and address of operator. x[sthename_pri] := "_uniq" x[sthename_pri] =># "`(ast_uniq ,_sr ,_2)"; x[sthename_pri] := "_rref" x[sthename_pri] =># "`(ast_rref ,_sr ,_2)"; x[sthename_pri] := "&<" x[sthename_pri] =># "`(ast_rref ,_sr ,_2)"; x[sthename_pri] := "_wref" x[sthename_pri] =># "`(ast_wref ,_sr ,_2)"; x[sthename_pri] := "&>" x[sthename_pri] =># "`(ast_wref ,_sr ,_2)"; //$ Felix address of operator. x[sthename_pri] := "label_address" sname =># "`(ast_label_ref ,_sr ,_2)"; //$ macro expansion freezer. x[sthename_pri] := "noexpand" squalified_name =># "`(ast_noexpand ,_sr ,_2)"; //$ pattern variable. x[sthename_pri] := "?" sname =># "`(ast_patvar ,_sr ,_2)"; //$ Template replacement index. x[sthename_pri] := "#?" sinteger =># "`(PARSER_ARGUMENT ,_2)"; x[sthename_pri] := squalified_name =># "_1"; //$ Qualified name. sreally_qualified_name := squalified_name "::" ssimple_name_parts =># "`(ast_lookup (,_1 ,(first _3) ,(second _3)))"; squalified_name := sreally_qualified_name =># '_1'; squalified_name := ssimple_name_parts =># "`(ast_name ,_sr ,(first _1) ,(second _1))"; ssimple_name_parts := sname =># "`(,_1 ())"; ssimple_name_parts := sname "[" "]" =># "`(,_1 ())"; ssimple_name_parts := sname "[" stypeexpr_comma_list "]" =># "`(,_1 ,_3)"; //$ Suffixed name (to name functions). ssuffixed_name := squalified_name "of" t[sthename_pri] =># "`(ast_suffix (,_1 ,_3))"; //------------------------------------------------------------------------ x[satomic_pri] := satom =># "_1"; //$ record value (comma separated). satom := "(" rassign ("," rassign2 )* ")" =># "`(ast_record ,_sr ,(cons _2 (map second _3)))" ; rassign := sname "=" x[sor_condition_pri] =># "`(,_1 ,_3)"; rassign := "=" x[sor_condition_pri] =># '`("" ,_2)'; rassign2 := sname "=" x[sor_condition_pri] =># "`(,_1 ,_3)"; rassign2 := "=" x[sor_condition_pri] =># '`("" ,_2)'; rassign2 := x[sor_condition_pri] =># '`("" ,_1)'; //$ polyrecord value //$ record value (comma separated). satom := "(" rassign ("," rassign2 )* "|" sexpr ")" =># "`(ast_polyrecord ,_sr ,(cons _2 (map second _3)) ,_5)" ; satom := "(" sexpr "without" sname+ ")" =># "`(ast_remove_fields ,_sr ,_2 ,_4)" ; satom := "(" sexpr "getall" sname ")" =># "`(ast_getall_field ,_sr ,_2 ,_4)" ; satom := "(" sexpr "with" rassign ("," rassign2 )* ")" =># "`(ast_replace_fields ,_sr ,_2 ,(cons _4 (map second _5)))" ; //$ record value, statement list. //$ this variant is useful for encapsulating //$ a series of var x = y; style statements. satom := "struct" "{" vassign+ "}" =># "`(ast_record ,_sr ,_3 )" ; vassign := "var" sname "=" sexpr ";" =># "`(,_2 ,_4)"; //$ scalar literals (numbers, strings). satom := sliteral =># "_1"; //$ Wildcard pattern. satom := _ =># "`(ast_patany ,_sr)"; //$ Callback expression. satom := "callback" "[" sexpr "]" =># "`(ast_callback ,_sr ,_3)"; //$ Short form anonymous procedure closure. satom := scompound =># "(lazy _1)"; //$ Short form sequence operator. //$ ( stmt; expr ) means the same as #{stmt; return expr; } satom := "(" stmt+ sexpr ")" =># """ ( let* ( (stmts _2) (expr _3) (retexp `(ast_fun_return ,_sr ,expr)) (nustmts (append stmts (list retexp))) ) (block_expr nustmts) ) """ ; //$ special anonymous variable forces eager eval. satom := "(" "var" sexpr ")" =># """ ( let ( (name (fresh_name "asvar")) ) `(ast_as_var ,_sr (,_3 ,name)) ) """ ; //$ inline scheme satom := "schemelex" sstring =># "(schemelex _2)"; satom := "schemerun" sstring =># "(schemerun _2)"; //$ Empty tuple (unit tuple). satom := "(" ")" =># "'()"; //$ Object extension. expr_comma_list := list::commalist1 =># "_1"; satom := "extend" expr_comma_list "with" sexpr "end" =># """ `(ast_extension ,_sr ,_2 ,_4) """; setbar := "|" =># "_1"; setbar := "\|" =># "_1"; setbar := "\mid" =># "_1"; setform := spattern ":" stypeexpr setbar sexpr =># """ (let* ( (argt _3) (ret (nos "bool")) (matchings `((,_1 ,_5)((pat_setform_any ,_sr)(ast_false ,_sr)))) (body `((ast_fun_return ,_sr (ast_match ,_sr (,(noi '_a) ,matchings))))) (param `(,_sr PVal _a ,argt none)) ;; one parameter (params `( Satom ,param )) ;; parameter tuple list (paramsx `(,params none)) ;; parameter tuple list with precondition (paramsxs `(,paramsx)) ;; curry parameters (method `(ast_curry ,_sr "has_elt" ,dfltvs ,paramsxs (,ret none) Method () ,body)) (objsts `(,method)) (object `(ast_object ,_sr (,dfltvs ,dfltparams typ_none ,objsts))) ) `(ast_apply ,_sr (,object (ast_tuple ,_sr ()))) ) """; satom := "{" setform "}" =># "_2"; satom := "\{" setform "\}" =># "_2"; satom := "@(" sexpr ")" =># """ `(ast_apply ,_sr (,(nos "objc_box") ,_2)) """ ; }