Files
astromaddie--HaloCE-VR/source/hs/hs_compile.c
T
Jonas Volman 6bfd956737 Reconcile approved Halo fidelity packets and bounded data credit
Recover transparent geometry submit (+1,285 meaningful code, zero exact losses); reconcile COMMON ownership and Q10 85+EXT1 credit, actions/main data, and separately disclosed denominator corrections. Preserve canonical-only repairs and all held research. C09 is ordinary disclosed cleanup, not a claim of proven scaffolding intent. Clean rebuild, 1,663 tests, parks, audits, provider links and independent EXT1 check pass. Local reconciliation only.
2026-09-29 13:52:37 -07:00

3395 lines
96 KiB
C

/*
HS_COMPILE.C
symbols in this file:
000B46B0 02c0:
_code_000b46b0 (0000)
000B4970 00b0:
_code_000b4970 (0000)
000B4A20 00b0:
_hs_compile_initialize (0000)
000B4AD0 0070:
_code_000b4ad0 (0000)
000B4B40 0030:
_hs_verify_source_offset (0000)
000B4B70 0050:
_code_000b4b70 (0000)
000B4BC0 0020:
_code_000b4bc0 (0000)
000B4BE0 0120:
_code_000b4be0 (0000)
000B4D00 00c0:
_code_000b4d00 (0000)
000B4DC0 0130:
_code_000b4dc0 (0000)
000B4EF0 00f0:
_code_000b4ef0 (0000)
000B4FE0 0120:
_code_000b4fe0 (0000)
000B5100 0080:
_code_000b5100 (0000)
000B5180 00b0:
_code_000b5180 (0000)
000B5230 00d0:
_code_000b5230 (0000)
000B5300 01d0:
_code_000b5300 (0000)
000B54D0 0100:
_code_000b54d0 (0000)
000B55D0 0070:
_code_000b55d0 (0000)
000B5640 0070:
_code_000b5640 (0000)
000B56B0 0070:
_code_000b56b0 (0000)
000B5720 0070:
_code_000b5720 (0000)
000B5790 0070:
_code_000b5790 (0000)
000B5800 0070:
_code_000b5800 (0000)
000B5870 00b0:
_code_000b5870 (0000)
000B5920 0070:
_code_000b5920 (0000)
000B5990 0070:
_code_000b5990 (0000)
000B5A00 0070:
_code_000b5a00 (0000)
000B5A70 0140:
_code_000b5a70 (0000)
000B5BB0 00a0:
_code_000b5bb0 (0000)
000B5C50 0090:
_code_000b5c50 (0000)
000B5CE0 0090:
_code_000b5ce0 (0000)
000B5D70 0060:
_code_000b5d70 (0000)
000B5DD0 0040:
_code_000b5dd0 (0000)
000B5E10 0090:
_code_000b5e10 (0000)
000B5EA0 0290:
_code_000b5ea0 (0000)
000B6130 0430:
_code_000b6130 (0000)
000B6560 00f0:
_code_000b6560 (0000)
000B6650 00f0:
_code_000b6650 (0000)
000B6740 0120:
_code_000b6740 (0000)
000B6860 0380:
_code_000b6860 (0000)
000B6BE0 02d0:
_hs_compile_postprocess (0000)
000B6EB0 00d0:
_code_000b6eb0 (0000)
000B6F80 00c0:
_code_000b6f80 (0000)
000B7040 00e0:
_code_000b7040 (0000)
000B7120 00d0:
_hs_parse (0000)
000B71F0 0120:
_hs_macro_function_parse (0000)
000B7310 01b0:
_hs_parse_begin (0000)
000B74C0 01c0:
_hs_parse_if (0000)
000B7680 00a0:
_hs_parse_cond (0000)
000B7720 0230:
_hs_parse_set (0000)
000B7950 0170:
_hs_parse_logical (0000)
000B7AC0 0190:
_hs_parse_arithmetic (0000)
000B7C50 0110:
_hs_parse_equality (0000)
000B7D60 01d0:
_hs_parse_inequality (0000)
000B7F30 00c0:
_hs_parse_sleep (0000)
000B7FF0 00e0:
_hs_parse_sleep_until (0000)
000B80D0 00d0:
_hs_parse_wake (0000)
000B81A0 00c0:
_hs_parse_inspect (0000)
000B8260 0080:
_hs_parse_object_cast_up (0000)
000B82E0 0110:
_hs_parse_debug_string (0000)
000B83F0 0260:
_hs_compile_expression (0000)
000B8650 0140:
_hs_compile (0000)
000B8790 0100:
_hs_compile_finish (0000)
000B8890 00d0:
_hs_compile_dispose (0000)
00269F98 00cc:
_whitespace_characters (0000)
_eol_characters (0004)
_hs_type_primitive_parsers (0008)
0026A064 0038:
??_C@_0DI@FFMILLMF@this?5argument?5to?5cond?5should?5be?5@ (0000)
0026A09C 0026:
??_C@_0CG@CKIGEJPJ@this?5argument?5to?5cond?5needs?5a?5re@ (0000)
0026A0C4 0023:
??_C@_0CD@IJMPPEHP@i?5couldn?8t?5allocate?5a?5syntax?5nod@ (0000)
0026A0E8 0023:
??_C@_0CD@CMPGDOHG@the?5?$CFs?5call?5requires?5?$CFd?5argument@ (0000)
0026A10C 0020:
??_C@_0CA@FLDPLDBJ@?$CBhs_compile_globals?4initialized?$AA@ (0000)
0026A12C 001f:
??_C@_0BP@MLCFIFLN@c?3?2halo?2SOURCE?2hs?2hs_compile?4c?$AA@ (0000)
0026A14C 002b:
??_C@_0CL@GBEGGBNG@bad?5source?5offset?5?$CIyou?5need?5to?5r@ (0000)
0026A178 0023:
??_C@_0CD@EFKPEBIG@this?5is?5not?5a?5valid?5variable?5nam@ (0000)
0026A19C 003f:
??_C@_0DP@PEGJCBIB@i?5expected?5a?5value?5of?5type?5?$CFs?0?5b@ (0000)
0026A1E0 0042:
??_C@_0EC@IIFEBBHH@hs_type_valid?$CIexpression?9?$DOtype?$CJ?5@ (0000)
0026A224 0020:
??_C@_0CA@DKEMPFLD@predicate?9?$DOfunction_index?$CB?$DNNONE?$AA@ (0000)
0026A244 001e:
??_C@_0BO@OIGMDMNN@i?5expected?5?$CCtrue?$CC?5or?5?$CCfalse?$CC?4?$AA@ (0000)
0026A264 0002:
??_C@_01HIHLOKLC@1?$AA@ (0000)
0026A268 0002:
??_C@_01GBGANLPD@0?$AA@ (0000)
0026A26C 002c:
??_C@_0CM@LMJJMGPB@expression?9?$DOconstant_type?$DN?$DNexpre@ (0000)
0026A298 0023:
??_C@_0CD@PDJAANOA@expression?9?$DOtype?$DN?$DN_hs_type_boole@ (0000)
0026A2BC 0021:
??_C@_0CB@OIAINLCH@this?5is?5not?5a?5valid?5real?5number?4@ (0000)
0026A2E0 0020:
??_C@_0CA@FDCELDHN@expression?9?$DOtype?$DN?$DN_hs_type_real?$AA@ (0000)
0026A300 002d:
??_C@_0CN@PNJHLLDG@shorts?5must?5be?5in?5the?5range?5?$FL?932@ (0000)
0026A330 001d:
??_C@_0BN@MIAGNDJA@this?5is?5not?5a?5valid?5integer?4?$AA@ (0000)
0026A350 0054:
??_C@_0FE@HAABGHID@expression?9?$DOtype?$DN?$DN_hs_type_short@ (0000)
0026A3A4 0022:
??_C@_0CC@NOGPGKAJ@expression?9?$DOtype?$DN?$DN_hs_type_strin@ (0000)
0026A3C8 0021:
??_C@_0CB@PILDPBCN@this?5is?5not?5a?5valid?5script?5name?4@ (0000)
0026A3EC 0022:
??_C@_0CC@LHOLJHMC@expression?9?$DOtype?$DN?$DN_hs_type_scrip@ (0000)
0026A410 002b:
??_C@_0CL@GNGCJOIJ@HS_TYPE_IS_TAG_REFERENCE?$CIexpress@ (0000)
0026A43C 0003:
??_C@_02DAHALNEP@?$CC?4?$AA@ (0000)
0026A440 0004:
??_C@_03HPAPFPCK@or?5?$AA@ (0000)
0026A444 0004:
??_C@_03HAFDNMHA@?$CC?0?5?$AA@ (0000)
0026A448 0002:
??_C@_01BJJEKLCA@?$CC?$AA@ (0000)
0026A44C 000c:
??_C@_0M@KDPMODNJ@?$CFs?5must?5be?5?$AA@ (0000)
0026A458 0017:
??_C@_0BH@KAIIDDCD@enum_definition?9?$DOcount?$AA@ (0000)
0026A470 0022:
??_C@_0CC@MAMGKIFK@HS_TYPE_IS_ENUM?$CIexpression?9?$DOtype@ (0000)
0026A494 001c:
??_C@_0BM@LLFLMGFD@this?5is?5not?5a?5valid?5?$CFs?5name?$AA@ (0000)
0026A4B0 0026:
??_C@_0CG@KJHDFGKE@offset?$CLTAG_STRING_LENGTH?$DMelement@ (0000)
0026A4D8 0018:
??_C@_0BI@DDGKIDCA@element_size?$DM?$DNSHORT_MAX?$AA@ (0000)
0026A4F0 003f:
??_C@_0DP@DDIGGJCL@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A530 003e:
??_C@_0DO@KIKHDLLO@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A570 0046:
??_C@_0EG@OIMEONBP@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A5B8 003f:
??_C@_0DP@NJJHMCPO@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A5F8 0043:
??_C@_0ED@MFJLLEIG@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A63C 003d:
??_C@_0DN@ENBCEMCP@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A67C 002b:
??_C@_0CL@GHINNEMH@this?5is?5not?5a?5valid?5ai?5encounter@ (0000)
0026A6A8 0033:
??_C@_0DD@BFEBGH@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A6E0 0040:
??_C@_0EA@CLIOJMOJ@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A720 0041:
??_C@_0EB@LFKOHNHB@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A764 003d:
??_C@_0DN@KMDNBPLF@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A7A4 0021:
??_C@_0CB@NGOPBJNH@this?5is?5not?5a?5valid?5object?5name?4@ (0000)
0026A7C8 0022:
??_C@_0CC@PHOMBDHG@this?5is?5not?5an?5object?5of?5type?5?$CFs@ (0000)
0026A7EC 0027:
??_C@_0CH@BODOHPOD@object_name?9?$DOruntime_object_type@ (0000)
0026A814 0029:
??_C@_0CJ@IEEDGBAJ@HS_TYPE_IS_OBJECT_NAME?$CIexpressio@ (0000)
0026A840 0024:
??_C@_0CE@OBCLMFIJ@HS_TYPE_IS_OBJECT?$CIexpression?9?$DOty@ (0000)
0026A864 0039:
??_C@_0DJ@MLDFNHMP@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A8A0 003c:
??_C@_0DM@NDFNDKDO@hs_syntax_get?$CIexpression_index?$CJ?9@ (0000)
0026A8DC 0027:
??_C@_0CH@KPEEOMPJ@expression?9?$DOtype?$DN?$DN_hs_type_objec@ (0000)
0026A904 0029:
??_C@_0CJ@MJLOCEH@ran?5out?5of?5script?5string?5constan@ (0000)
0026A930 0031:
??_C@_0DB@KNNKPLIC@i?5expected?5?$CIglobal?$DMtype?$DO?5?$DMname?$DO?5@ (0000)
0026A964 003b:
??_C@_0DL@HEBOLCPD@i?5expected?5a?5global?5variable?5nam@ (0000)
0026A9A0 002a:
??_C@_0CK@ILPHLOJN@there?5is?5already?5a?5variable?5by?5t@ (0000)
0026A9CC 002b:
??_C@_0CL@FLFKBOAG@i?5couldn?8t?5allocate?5space?5for?5th@ (0000)
0026A9F8 001a:
??_C@_0BK@IKPJOEIK@this?5is?5not?5a?5valid?5type?4?$AA@ (0000)
0026AA14 0032:
??_C@_0DC@LIKMAGAH@i?5expected?5?$CIscript?5?$DMtype?$DO?5?$DMname?$DO@ (0000)
0026AA48 0037:
??_C@_0DH@HLEPKBGC@i?5expected?5?$CIscript?5stub?5?$DMtype?$DO?5?$DM@ (0000)
0026AA80 0039:
??_C@_0DJ@ICFJDLL@i?5expected?5?$CIscript?5static?5?$DMtype?$DO@ (0000)
0026AABC 0032:
??_C@_0DC@KKMNLEGD@i?5expected?5a?5script?5name?5less?5th@ (0000)
0026AAF0 0040:
??_C@_0EA@JEODPONE@only?5static?5scripts?5of?5the?5same?5@ (0000)
0026AB30 001e:
??_C@_0BO@DIEOOMIB@i?5couldn?8t?5allocate?5a?5script?4?$AA@ (0000)
0026AB50 0039:
??_C@_0DJ@KPBLJMAG@i?5expected?5?$CIscript?5local?5?$DMtype?$DO?5@ (0000)
0026AB8C 0021:
??_C@_0CB@IMBMFBPE@this?5is?5not?5a?5valid?5return?5type?4@ (0000)
0026ABB0 0045:
??_C@_0EF@HPGCPNKB@script?5type?5must?5be?5?$CCstartup?$CC?0?5?$CC@ (0000)
0026ABF8 0026:
??_C@_0CG@DLDLACEH@this?5quoted?5constant?5is?5untermin@ (0000)
0026AC20 0016:
??_C@_0BG@OBOCFOLJ@unterminated?5comment?4?$AA@ (0000)
0026AC38 0032:
??_C@_0DC@DNDDDIBA@expressions?5of?5type?5?$CFs?5are?5curre@ (0000)
0026AC70 0043:
??_C@_0ED@BCCOKIBI@the?5value?5of?5this?5expression?5?$CIin@ (0000)
0026ACB4 002c:
??_C@_0CM@DJEKPL@i?5expected?5a?5script?5or?5variable?5@ (0000)
0026ACE0 0068:
??_C@_0GI@BHJPJIIC@hs_type_valid?$CIexpression?9?$DOtype?$CJ?5@ (0000)
0026AD48 0028:
??_C@_0CI@NKPOIECC@i?5expected?5?$CFs?0?5but?5i?5got?5an?5expr@ (0000)
0026AD70 0010:
??_C@_0BA@PAKINOFK@a?5function?5name?$AA@ (0000)
0026AD80 0015:
??_C@_0BF@IBMEIANF@?$CCscript?$CC?5or?5?$CCglobal?$CC?$AA@ (0000)
0026AD98 002d:
??_C@_0CN@EDPOFKO@this?5is?5not?5a?5valid?5function?5or?5@ (0000)
0026ADC8 0010:
??_C@_0BA@LKPMJEGC@function?9?$DOparse?$AA@ (0000)
0026ADD8 003d:
??_C@_0DN@MBGBMIIG@it?5is?5illegal?5to?5set?5the?5value?5o@ (0000)
0026AE18 0028:
??_C@_0CI@LEFIJLGP@it?5is?5illegal?5to?5block?5in?5this?5c@ (0000)
0026AE40 0031:
??_C@_0DB@FJPDKKBL@i?5expected?5a?5?$CFs?0?5but?5this?5functi@ (0000)
0026AE74 002f:
??_C@_0CP@EBGMPNCK@i?5expected?5a?5?$CFs?0?5but?5this?5script@ (0000)
0026AEA4 001d:
??_C@_0BN@IHENCGGJ@this?5is?5not?5a?5static?5script?4?$AA@ (0000)
0026AEC4 0021:
??_C@_0CB@IAHJHNPF@i?5expected?5?$CCscript?$CC?5or?5?$CCglobal?$CC?4@ (0000)
0026AEE8 002e:
??_C@_0CO@BFGOLJBG@missing?5type?5?$CIyou?5need?5to?5recomp@ (0000)
0026AF18 0041:
??_C@_0EB@EJKNFGEH@type?5is?5inconsistent?5with?5usage?5@ (0000)
0026AF5C 0035:
??_C@_0DF@DBAKANGN@corrupt?5syntax?5tree?5?$CIyou?5need?5to@ (0000)
0026AF94 0032:
??_C@_0DC@LGOKBIPD@missing?5function?5?$CIyou?5need?5to?5re@ (0000)
0026AFC8 002a:
??_C@_0CK@DLLKHDNE@bad?5script?5index?5?$CIyou?5need?5to?5re@ (0000)
0026AFF4 001a:
??_C@_0BK@BFLBDCPG@?$CBhs_compile_globals?4error?$AA@ (0000)
0026B010 001a:
??_C@_0BK@NAGDEHOO@this?5expression?5is?5empty?4?$AA@ (0000)
0026B02C 0024:
??_C@_0CE@GGGJMCLA@this?5left?5parenthesis?5is?5unmatch@ (0000)
0026B050 005f:
??_C@_0FP@FAMPHEFE@hs_type_valid?$CIexpected_type?$CJ?5?$HM?$HM?5@ (0000)
0026B0B0 002d:
??_C@_0CN@KIPPILAN@the?5?$CC?$CFs?$CC?5call?5requires?5exactly?5?$CF@ (0000)
0026B0E0 0027:
??_C@_0CH@HOBBAFGG@hs_type_valid?$CIdefinition?9?$DOreturn@ (0000)
0026B108 004a:
??_C@_0EK@BFPAJKIG@begin_random?5can?5take?5a?5maximum?5@ (0000)
0026B154 0036:
??_C@_0DG@ILKKMIFN@a?5statement?5block?5must?5contain?5a@ (0000)
0026B190 0050:
??_C@_0FA@MLNKNPCC@function_index?$DN?$DN_hs_function_beg@ (0000)
0026B1E0 0030:
??_C@_0DA@FDDIOHDH@c?3?2halo?2source?2hs?2hs_library_int@ (0000)
0026B210 002d:
??_C@_0CN@FFHDLAIG@i?5expected?5?$CIif?5?$DMcondition?$DO?5?$DMthen@ (0000)
0026B240 0020:
??_C@_0CA@JPNHPBMJ@function_index?$DN?$DN_hs_function_if?$AA@ (0000)
0026B260 002a:
??_C@_0CK@FOEIDHHM@i?5expected?5a?5variable?5to?5set?5and@ (0000)
0026B28C 0020:
??_C@_0CA@PGGJICDP@i?5expected?5an?5assignment?5value?4?$AA@ (0000)
0026B2AC 001f:
??_C@_0BP@FENPFJFI@i?5didn?8t?5expect?5this?5argument?4?$AA@ (0000)
0026B2CC 0025:
??_C@_0CF@JLOHFOAN@this?5is?5not?5a?5valid?5global?5varia@ (0000)
0026B2F4 0009:
??_C@_08NNEKJPJG@asserted?$AA@ (0000)
0026B300 0055:
??_C@_0FF@OKNDBCCJ@you?5cannot?5pass?5the?5result?5of?5th@ (0000)
0026B358 002b:
??_C@_0CL@HLGBMAID@the?5?$CFs?5call?5requires?5at?5least?52?5@ (0000)
0026B388 0044:
??_C@_0EE@DJKKNFEH@function_index?$DN?$DN_hs_function_and@ (0000)
0026B3CC 0024:
??_C@_0CE@JPJPEJGL@the?5?$CFs?5call?5requires?5?$CFs2?5argumen@ (0000)
0026B3F0 000a:
??_C@_09HJOCAFJB@at?5least?5?$AA@ (0000)
0026B400 0046:
??_C@_0EG@NCMDIGON@function_index?$DO?$DN_hs_function_plu@ (0000)
0026B448 004d:
??_C@_0EN@LKLJPEDN@function_index?$DN?$DN_hs_function_equ@ (0000)
0026B498 0044:
??_C@_0EE@DBJLFPAO@function_index?$DO?$DN_hs_function_gt?5@ (0000)
0026B4DC 003f:
??_C@_0DP@OBLOAKOC@the?5sleep?5call?5requires?5a?5time?5a@ (0000)
0026B51C 0023:
??_C@_0CD@OEIHEIL@function_index?$DN?$DN_hs_function_sle@ (0000)
0026B540 0045:
??_C@_0EF@ONCEJGKM@the?5sleep_until?5call?5requires?5a?5@ (0000)
0026B588 0029:
??_C@_0CJ@OOHINAAD@function_index?$DN?$DN_hs_function_sle@ (0000)
0026B5B4 0027:
??_C@_0CH@LDNCEPBK@this?5static?5script?5cannot?5be?5awa@ (0000)
0026B5DC 0022:
??_C@_0CC@MOINJLCD@function_index?$DN?$DN_hs_function_wak@ (0000)
0026B600 0048:
??_C@_0EI@PCGFDELO@this?5is?5not?5a?5global?5variable?5re@ (0000)
0026B648 0025:
??_C@_0CF@OOHBFBHF@function_index?$DN?$DN_hs_function_ins@ (0000)
0026B670 005b:
??_C@_0FL@GHADBDBJ@function_index?$DO?$DN_hs_function_obj@ (0000)
0026B6D0 0068:
??_C@_0GI@HCJMIFHN@?$CIfunction_index?$DO?$DN_hs_function_de@ (0000)
0026B738 0052:
??_C@_0FC@BMHAGKNK@hs_compile_globals?4error_offset?$DO@ (0000)
0026B78C 0023:
??_C@_0CD@IOHANEHH@hs_compile_globals?4compiled_sour@ (0000)
0026B7B0 0056:
??_C@_0FG@HHFCBJJH@global_scenario_get?$CI?$CJ?9?$DOhs_string@ (0000)
0026B808 002e:
??_C@_0CO@JFMALCKF@couldn?8t?5allocate?5memory?5for?5com@ (0000)
0026B838 0057:
??_C@_0FH@BKGDNNEC@hs_compile_globals?4error_offset?$DO@ (0000)
0026B890 0044:
??_C@_0EE@JNFGKPCH@tell?5matt?5that?5somebody?5failed?5t@ (0000)
0026B8D4 002d:
??_C@_0CN@CMJJHKPH@increase?5MAXIMUM_HS_STRING_DATA_@ (0000)
0026B904 001f:
??_C@_0BP@OAFEJCHM@hs_compile_globals?4initialized?$AA@ (0000)
00453480 012c:
_bss_00453480 (0000)
*/
/* ---------- headers */
#include "cseries/cseries.h"
#include "cache/cache_files.h"
#include "ai/ai_script.h"
#include "hs/hs.h"
#include "hs/hs_library_internal.h"
#include "hs/hs_library_internal_compile.h"
#include "hs/hs_scenario_definitions.h"
#include "interface/hud_definitions.h"
#include "interface/interface.h"
#include "memory/data.h"
#include "scenario/scenario.h"
#include "scenario/scenario_definitions.h"
/* ---------- constants */
enum
{
first_hs_object_type = _hs_type_object,
first_hs_object_name_type = _hs_type_object_name,
MAXIMUM_HS_BEGIN_RANDOM_ARGUMENTS = 32,
HS_MAXIMUM_DYNAMIC_SOURCE_DATA_BYTES = 0x400,
scenario_cutscene_flag_size = 0x5C,
scenario_cutscene_title_size = 0x60,
scenario_recorded_animation_size = 0x40,
scenario_device_group_size = 0x34,
scenario_ai_command_list_size = 0x60,
scenario_conversation_size = 0x74,
hud_globals_group_tag = 'hudg',
hud_message_text_group_tag = 'hmt ',
hud_waypoint_arrow_size = 0x68,
hud_message_definition_size = 0x40,
};
enum hs_syntax_node_flag_bits
{
_hs_syntax_node_primitive_bit = 0,
_hs_syntax_node_script_bit,
_hs_syntax_node_variable_bit,
_hs_syntax_node_permanent_bit,
};
enum hs_tokenizer_state
{
_hs_tokenizer_state_normal = 0,
_hs_tokenizer_state_line_comment,
_hs_tokenizer_state_block_comment,
_hs_tokenizer_state_done,
};
/* ---------- macros */
#define hs_syntax_get(expression_index) ((struct hs_syntax_node *)datum_get(hs_syntax_data, (expression_index)))
#define hud_globals_definition_get(index) ((struct hud_globals_definition *)tag_get(hud_globals_group_tag, (index)))
#define hud_message_text_definition_get(index) ((struct hud_message_text_definition *)tag_get(hud_message_text_group_tag, (index)))
#undef HS_TYPE_IS_OBJECT
#undef HS_TYPE_IS_OBJECT_NAME
#define HS_TYPE_IS_OBJECT(type) ((type)>=first_hs_object_type && (type)<=first_hs_object_type+NUMBER_OF_HS_OBJECT_TYPES-1)
#define HS_TYPE_IS_OBJECT_NAME(type) ((type)>=first_hs_object_name_type && (type)<=first_hs_object_name_type+NUMBER_OF_HS_OBJECT_TYPES-1)
/* ---------- structures */
struct hs_compile_globals
{
boolean initialized;
byte pad001[3];
long compiled_source_size;
char *compiled_source;
char *string_constant_buffer;
long string_constant_buffer_offset;
long string_constant_buffer_size;
boolean error_since_initialize;
byte pad019[3];
char const *error;
long error_offset;
char error_buffer[256];
boolean malloced;
boolean compiling_scenario;
boolean disallow_blocks;
boolean disallow_sets;
boolean variables_predetermined;
byte pad129[3];
};
struct hs_tokenizer
{
char *cursor;
};
typedef char verify_hs_syntax_node_size[
sizeof(struct hs_syntax_node) == 0x14 ? 1 : -1];
struct hud_message_text_definition
{
byte reserved000[0x20];
struct tag_block messages;
};
typedef boolean (*hs_primitive_parser)(
long expression_index);
typedef char verify_hs_compile_initialized_offset[
offsetof(struct hs_compile_globals, initialized) == 0x00 ? 1 : -1];
typedef char verify_hs_compile_compiled_source_size_offset[
offsetof(struct hs_compile_globals, compiled_source_size) == 0x04 ? 1 : -1];
typedef char verify_hs_compile_compiled_source_offset[
offsetof(struct hs_compile_globals, compiled_source) == 0x08 ? 1 : -1];
typedef char verify_hs_compile_string_constant_buffer_offset[
offsetof(struct hs_compile_globals, string_constant_buffer) == 0x0C ? 1 : -1];
typedef char verify_hs_compile_error_since_initialize_offset[
offsetof(struct hs_compile_globals, error_since_initialize) == 0x18 ? 1 : -1];
typedef char verify_hs_compile_error_offset[
offsetof(struct hs_compile_globals, error) == 0x1C ? 1 : -1];
typedef char verify_hs_compile_compiling_scenario_offset[
offsetof(struct hs_compile_globals, compiling_scenario) == 0x125 ? 1 : -1];
typedef char verify_hs_compile_globals_size[
sizeof(struct hs_compile_globals) == 0x12C ? 1 : -1];
/* ---------- prototypes */
static boolean hs_parse_scenario_datum(
long expression_index,
short offset,
struct tag_block *block,
long element_size);
static boolean hs_parse_trigger_volume(
long expression_index);
static boolean hs_parse_cutscene_flag(
long expression_index);
static boolean hs_parse_cutscene_camera_point(
long expression_index);
static boolean hs_parse_cutscene_title(
long expression_index);
static boolean hs_parse_cutscene_recording(
long expression_index);
static boolean hs_parse_device_group(
long expression_index);
static boolean hs_parse_ai_command_list(
long expression_index);
static boolean hs_parse_starting_profile(
long expression_index);
static boolean hs_parse_conversation(
long expression_index);
static boolean hs_parse_boolean(
long expression_index);
static boolean hs_parse_real(
long expression_index);
static boolean hs_parse_integer(
long expression_index);
static boolean hs_parse_string(
long expression_index);
static boolean hs_parse_script(
long expression_index);
static boolean hs_parse_tag_reference(
long expression_index);
static boolean hs_parse_enum(
long expression_index);
static boolean hs_parse_ai(
long expression_index);
static boolean hs_parse_object_name(
long expression_index);
static boolean hs_parse_object(
long expression_index);
static boolean hs_parse_navpoint(
long expression_index);
static boolean hs_parse_hud_message(
long expression_index);
static boolean hs_parse_object_list(
long expression_index);
static char *hs_compile_add_source(
long source_size,
char const *source);
static boolean hs_get_parameter_indices(
char const *function_name,
short parameter_count,
long *parameter_indices,
long expression_index);
static void hs_compile_finish(
void);
static long hs_find_string_constant(
char const *string);
static boolean character_in_list(
char character,
short list_count,
char const *list);
static boolean hs_parse_variable(
long expression_index);
static void hs_parse_call_predicate(
long expression_index);
static short string_list_find(
char const *string,
short list_count,
char const **list);
static long hs_concatenate_string_constant(
char const *string);
static boolean hs_add_global(
long expression_index);
static boolean hs_add_script(
long expression_index);
static void hs_tokenize_primitive(
struct hs_tokenizer *tokenizer,
long expression_index);
static void skip_whitespace(
char **cursor);
static boolean hs_parse_primitive(
long expression_index);
static boolean hs_parse_nonprimitive(
long expression_index);
static void hs_concatenate_expression(
long expression_index);
static long hs_tokenize(
struct hs_tokenizer *tokenizer);
static void hs_tokenize_nonprimitive(
struct hs_tokenizer *tokenizer,
long expression_index);
/* ---------- globals */
extern struct data_array *hs_syntax_data;
static struct hs_compile_globals hs_compile_globals;
char const whitespace_characters[2] = { ' ', '\t' };
char const eol_characters[2] = { '\n', '\r' };
hs_primitive_parser const hs_type_primitive_parsers[NUMBER_OF_HS_TYPES] =
{
NULL,
NULL,
NULL,
NULL,
NULL,
hs_parse_boolean,
hs_parse_real,
hs_parse_integer,
hs_parse_integer,
hs_parse_string,
hs_parse_script,
hs_parse_trigger_volume,
hs_parse_cutscene_flag,
hs_parse_cutscene_camera_point,
hs_parse_cutscene_title,
hs_parse_cutscene_recording,
hs_parse_device_group,
hs_parse_ai,
hs_parse_ai_command_list,
hs_parse_starting_profile,
hs_parse_conversation,
hs_parse_navpoint,
hs_parse_hud_message,
hs_parse_object_list,
hs_parse_tag_reference,
hs_parse_tag_reference,
hs_parse_tag_reference,
hs_parse_tag_reference,
hs_parse_tag_reference,
hs_parse_tag_reference,
hs_parse_tag_reference,
hs_parse_tag_reference,
hs_parse_enum,
hs_parse_enum,
hs_parse_enum,
hs_parse_enum,
hs_parse_enum,
hs_parse_object,
hs_parse_object,
hs_parse_object,
hs_parse_object,
hs_parse_object,
hs_parse_object,
hs_parse_object_name,
hs_parse_object_name,
hs_parse_object_name,
hs_parse_object_name,
hs_parse_object_name,
hs_parse_object_name,
};
/* ---------- private code */
static long hs_parse_cond_recursive(
long root_expression_index,
long expression_index)
{
long new_expression_index = datum_new(hs_syntax_data);
if (new_expression_index != NONE)
{
struct hs_syntax_node *new_expression = hs_syntax_get(new_expression_index);
new_expression->source_offset = hs_syntax_get(root_expression_index)->source_offset;
new_expression->flags = 0;
new_expression->next_node_index = NONE;
if (expression_index == NONE)
{
short root_type;
new_expression->flags = FLAG(_hs_syntax_node_primitive_bit);
root_type = hs_syntax_get(root_expression_index)->type;
new_expression->constant_type = root_type;
new_expression->type = root_type;
new_expression->data = 0;
}
else if (!TEST_FLAG(hs_syntax_get(expression_index)->flags, _hs_syntax_node_primitive_bit))
{
long condition_expression_index = hs_syntax_get(expression_index)->data;
struct hs_syntax_node *condition_expression = hs_syntax_get(condition_expression_index);
/* BUG (preserved for exact matching): January tests the logical negation of the
* result index against NONE, which is never true, so a clause without a result is
* not rejected here. A corrected build tests
* condition_expression->next_node_index != NONE. */
if (!condition_expression->next_node_index != NONE)
{
long if_then_expression_index = datum_new(hs_syntax_data);
long then_value_expression_index = datum_new(hs_syntax_data);
if (if_then_expression_index != NONE && then_value_expression_index != NONE)
{
struct hs_syntax_node *if_then_expression = hs_syntax_get(if_then_expression_index);
struct hs_syntax_node *then_value_expression = hs_syntax_get(then_value_expression_index);
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
if_then_expression->next_node_index = hs_parse_cond_recursive(
root_expression_index,
hs_syntax_get(expression_index)->next_node_index);
if (if_then_expression->next_node_index != NONE)
{
new_expression->constant_type = _hs_function_name;
new_expression->data = expression_index;
expression->data = 0;
expression->function_index = _hs_function_if;
expression->flags = FLAG(_hs_syntax_node_primitive_bit);
expression->next_node_index = condition_expression_index;
expression->source_offset = NONE;
expression->type = _hs_function_name;
if_then_expression->data = then_value_expression_index;
if_then_expression->flags = 0;
if_then_expression->source_offset = new_expression->source_offset;
then_value_expression->data = 0;
then_value_expression->function_index = _hs_function_begin;
then_value_expression->flags = FLAG(_hs_syntax_node_primitive_bit);
then_value_expression->next_node_index = hs_syntax_get(condition_expression_index)->next_node_index;
then_value_expression->source_offset = NONE;
then_value_expression->type = _hs_function_name;
condition_expression->next_node_index = if_then_expression_index;
}
else
{
new_expression_index = NONE;
}
}
else
{
hs_compile_globals.error = "i couldn't allocate a syntax node.";
hs_compile_globals.error_offset = hs_syntax_get(root_expression_index)->source_offset;
new_expression_index = NONE;
}
}
else
{
hs_compile_globals.error = "this argument to cond needs a result.";
hs_compile_globals.error_offset = hs_syntax_get(condition_expression_index)->source_offset;
new_expression_index = NONE;
}
}
else
{
hs_compile_globals.error = "this argument to cond should be a condition/result pair";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
new_expression_index = NONE;
}
}
else
{
hs_compile_globals.error = "i couldn't allocate a syntax node.";
hs_compile_globals.error_offset = hs_syntax_get(root_expression_index)->source_offset;
}
return new_expression_index;
}
static boolean hs_get_parameter_indices(
char const *function_name,
short parameter_count,
long *parameter_indices,
long expression_index)
{
boolean result = TRUE;
long parameter_expression_index = hs_syntax_get(hs_syntax_get(expression_index)->data)->next_node_index;
short parameter_index;
for (parameter_index = 0;
parameter_expression_index != NONE;
parameter_expression_index = hs_syntax_get(parameter_expression_index)->next_node_index,
parameter_index++)
{
if (parameter_index >= parameter_count)
break;
parameter_indices[parameter_index] = parameter_expression_index;
}
if (parameter_index != parameter_count || parameter_expression_index != NONE)
{
sprintf(
hs_compile_globals.error_buffer,
"the %s call requires %d arguments.",
function_name,
parameter_count);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
result = FALSE;
}
return result;
}
/* ---------- public code */
void hs_compile_initialize(
boolean compiling_scenario)
{
struct scenario *scenario;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x5B,
!hs_compile_globals.initialized);
hs_compile_globals.initialized = TRUE;
hs_compile_globals.compiled_source = NULL;
hs_compile_globals.compiled_source_size = 0;
hs_compile_globals.compiling_scenario = compiling_scenario;
hs_compile_globals.error_since_initialize = FALSE;
hs_compile_globals.error = NULL;
if (compiling_scenario)
{
scenario = global_scenario_get();
tag_block_resize(&scenario->hs_scripts, 0);
tag_block_resize(&scenario->hs_globals, 0);
tag_block_resize(&scenario->hs_references, 0);
tag_data_resize(&scenario->hs_string_constants, 0);
data_delete_all(hs_syntax_data);
}
return;
}
void hs_compile_dispose(
void)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x75,
hs_compile_globals.initialized);
if (hs_compile_globals.compiling_scenario)
{
if (!hs_compile_globals.error_since_initialize)
{
hs_compile_finish();
}
else
{
struct scenario *scenario = global_scenario_get();
tag_block_resize(&scenario->hs_scripts, 0);
tag_block_resize(&scenario->hs_globals, 0);
tag_data_resize(&scenario->hs_string_constants, 0);
data_delete_all(hs_syntax_data);
}
if (hs_compile_globals.compiled_source)
{
match_free(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x87,
hs_compile_globals.compiled_source);
}
}
if (hs_compile_globals.malloced)
{
match_free(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x8C,
hs_compile_globals.compiled_source);
hs_compile_globals.compiled_source = NULL;
hs_compile_globals.malloced = FALSE;
}
hs_compile_globals.initialized = FALSE;
return;
}
long hs_compile_expression(
long source_size,
char const *source,
char const **error_message,
char const **error_source)
{
struct hs_tokenizer tokenizer;
long expression_index;
long begin_expression_index;
long root_expression_index;
long source_offset;
long result = NONE;
if (source_size < HS_MAXIMUM_DYNAMIC_SOURCE_DATA_BYTES)
{
if (global_scenario_index != NONE)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0xA6,
global_scenario_get()->hs_string_constants.size>=HS_MAXIMUM_DYNAMIC_SOURCE_DATA_BYTES);
source_offset = global_scenario_get()->hs_string_constants.size - HS_MAXIMUM_DYNAMIC_SOURCE_DATA_BYTES;
hs_compile_globals.compiled_source = global_scenario_get()->hs_string_constants.address;
}
else
{
source_offset = 0;
hs_compile_globals.compiled_source = match_malloc(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0xAF,
source_size + 1);
hs_compile_globals.malloced = TRUE;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0xB2,
hs_compile_globals.compiled_source);
}
memcpy(hs_compile_globals.compiled_source + source_offset, source, source_size);
hs_compile_globals.compiled_source_size = source_offset + source_size;
hs_compile_globals.compiled_source[hs_compile_globals.compiled_source_size] = 0;
tokenizer.cursor = hs_compile_globals.compiled_source + source_offset;
hs_compile_globals.error = NULL;
*error_message = NULL;
*error_source = NULL;
hs_compile_globals.error_offset = NONE;
skip_whitespace(&tokenizer.cursor);
if (*tokenizer.cursor)
{
expression_index = hs_tokenize(&tokenizer);
if (!hs_compile_globals.error)
{
root_expression_index = datum_new(hs_syntax_data);
begin_expression_index = datum_new(hs_syntax_data);
if (root_expression_index != NONE && begin_expression_index != NONE)
{
struct hs_syntax_node *root_expression = hs_syntax_get(root_expression_index);
struct hs_syntax_node *begin_expression = hs_syntax_get(begin_expression_index);
root_expression->data = begin_expression_index;
root_expression->next_node_index = NONE;
root_expression->source_offset = hs_syntax_get(expression_index)->source_offset;
root_expression->flags = 0;
begin_expression->next_node_index = expression_index;
begin_expression->source_offset = NONE;
begin_expression->function_index = _hs_function_inspect;
begin_expression->flags = FLAG(_hs_syntax_node_primitive_bit);
begin_expression->type = _hs_function_name;
if (hs_parse(root_expression_index, _hs_type_void))
result = root_expression_index;
}
}
if (result == NONE)
{
*error_message = hs_compile_globals.error;
if (hs_compile_globals.error_offset != NONE)
{
hs_compile_globals.error_offset -= source_offset;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0xEB,
hs_compile_globals.error_offset>=0 && hs_compile_globals.error_offset<source_size);
*error_source = source + hs_compile_globals.error_offset;
}
}
}
}
return result;
}
/* ---------- private code */
static char *hs_compile_add_source(
long source_size,
char const *source)
{
char *result = NULL;
char *compiled_source = match_realloc(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0xFD,
hs_compile_globals.compiled_source,
hs_compile_globals.compiled_source_size + source_size + 1);
if (compiled_source)
{
hs_compile_globals.compiled_source = compiled_source;
result = compiled_source + hs_compile_globals.compiled_source_size;
memcpy(result, source, source_size);
hs_compile_globals.compiled_source_size += source_size;
hs_compile_globals.compiled_source[hs_compile_globals.compiled_source_size] = 0;
}
return result;
}
void hs_compile(
long source_file_size,
char const *source,
char const **error_message,
char const **error_source)
{
struct hs_tokenizer tokenizer;
boolean valid;
tokenizer.cursor = hs_compile_add_source(source_file_size, source);
if (tokenizer.cursor)
{
hs_compile_globals.error = NULL;
*error_message = NULL;
*error_source = NULL;
valid = TRUE;
hs_compile_globals.error_offset = NONE;
skip_whitespace(&tokenizer.cursor);
do
{
long expression_index;
if (!*tokenizer.cursor)
break;
expression_index = hs_tokenize(&tokenizer);
skip_whitespace(&tokenizer.cursor);
valid = !hs_compile_globals.error;
if (valid)
valid = hs_parse(expression_index, _hs_special_form);
}
while (valid);
if (!valid)
{
match_vassert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x131,
hs_compile_globals.error,
"tell matt that somebody failed to correctly report a parsing error.");
*error_message = hs_compile_globals.error;
hs_compile_globals.error_since_initialize = TRUE;
if (hs_compile_globals.error_offset != NONE)
{
hs_compile_globals.error_offset -= hs_compile_globals.compiled_source_size - source_file_size;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x13B,
hs_compile_globals.error_offset>=0 && hs_compile_globals.error_offset<source_file_size);
*error_source = source + hs_compile_globals.error_offset;
}
}
}
else
{
*error_message = "couldn't allocate memory for compiled source.";
}
return;
}
static void hs_compile_finish(
void)
{
struct scenario *scenario = global_scenario_get();
boolean success = tag_data_resize(
&scenario->hs_string_constants,
hs_compile_globals.compiled_source_size);
short global_index;
short script_index;
if (success)
{
hs_compile_globals.string_constant_buffer = scenario->hs_string_constants.address;
hs_compile_globals.string_constant_buffer_offset = 0;
hs_compile_globals.string_constant_buffer_size = hs_compile_globals.compiled_source_size;
for (global_index = 0; global_index < scenario->hs_globals.count; global_index++)
{
struct hs_global *global = TAG_BLOCK_GET_ELEMENT(
&global_scenario_get()->hs_globals,
global_index,
struct hs_global);
hs_concatenate_expression(global->initialization_expression_index);
}
for (script_index = 0; script_index < scenario->hs_scripts.count; script_index++)
{
struct hs_script *script = TAG_BLOCK_GET_ELEMENT(
&scenario->hs_scripts,
script_index,
struct hs_script);
hs_concatenate_expression(script->root_expression_index);
}
hs_node_gc();
success = tag_data_resize(
&scenario->hs_string_constants,
hs_compile_globals.string_constant_buffer_offset +
HS_MAXIMUM_DYNAMIC_SOURCE_DATA_BYTES);
}
match_vassert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x16D,
success,
"increase MAXIMUM_HS_STRING_DATA_PER_SCENARIO");
return;
}
boolean hs_verify_source_offset(
long source_offset)
{
boolean valid;
valid = TRUE;
if (source_offset < 0 || source_offset >= hs_compile_globals.compiled_source_size)
{
hs_compile_globals.error = "bad source offset (you need to recompile.)";
valid = FALSE;
}
return valid;
}
static long hs_find_string_constant(
char const *string)
{
long offset = 0;
while (offset < hs_compile_globals.string_constant_buffer_offset)
{
char const *existing_string = hs_compile_globals.string_constant_buffer + offset;
if (strcmp(string, existing_string) == 0)
return offset;
offset += strlen(existing_string) + 1;
}
return NONE;
}
static boolean character_in_list(
char character,
short list_count,
char const *list)
{
short character_index;
for (character_index = 0; character_index < list_count; character_index++)
{
if (character == list[character_index])
return TRUE;
}
return FALSE;
}
static boolean hs_parse_variable(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
boolean result = FALSE;
long global_index;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x4E4,
hs_type_valid(expression->type) || expression->type==_hs_unparsed);
global_index = hs_find_global_by_name(
hs_compile_globals.compiled_source + expression->source_offset);
expression->data = global_index;
if (global_index != NONE)
{
short global_type = hs_global_get_type((short)expression->data);
if (expression->type && !hs_can_cast(global_type, expression->type))
{
sprintf(
hs_compile_globals.error_buffer,
"i expected a value of type %s, but the variable %s has type %s",
hs_type_names[expression->type],
hs_global_get_name((short)expression->data),
hs_type_names[global_type]);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = expression->source_offset;
}
else
{
if (!expression->type)
expression->type = global_type;
SET_FLAG(expression->flags, _hs_syntax_node_variable_bit, TRUE);
result = TRUE;
}
}
else if (hs_compile_globals.variables_predetermined)
{
hs_compile_globals.error = "this is not a valid variable name.";
hs_compile_globals.error_offset = expression->source_offset;
result = FALSE;
}
return result;
}
static void hs_parse_call_predicate(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
long predicate_index = hs_syntax_get(expression_index)->data;
struct hs_syntax_node *predicate = hs_syntax_get(predicate_index);
if (predicate->type != _hs_function_name)
{
expression->function_index = hs_find_function_by_name(
hs_compile_globals.compiled_source + predicate->source_offset);
predicate->type = _hs_function_name;
if (expression->function_index == NONE)
{
expression->function_index = hs_find_script_by_name(
hs_compile_globals.compiled_source + predicate->source_offset);
if (expression->function_index != NONE)
SET_FLAG(expression->flags, _hs_syntax_node_script_bit, TRUE);
}
predicate->function_index = expression->function_index;
}
else
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x520,
predicate->function_index!=NONE);
expression->function_index = predicate->function_index;
}
return;
}
static boolean hs_parse_boolean(
long expression_index)
{
boolean result = TRUE;
boolean value;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
char const *string = hs_compile_globals.compiled_source + expression->source_offset;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x5B3,
expression->type==_hs_type_boolean);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x5B4,
expression->constant_type==expression->type);
if (csstrcmp(string, "false") == 0 ||
csstrcmp(string, "off") == 0 ||
csstrcmp(string, "0") == 0)
{
value = FALSE;
}
else if (csstrcmp(string, "true") == 0 ||
csstrcmp(string, "on") == 0 ||
csstrcmp(string, "1") == 0)
{
value = TRUE;
}
else
{
hs_compile_globals.error = "i expected \"true\" or \"false\".";
hs_compile_globals.error_offset = expression->source_offset;
result = FALSE;
}
if (result)
expression->boolean_value = value;
return result;
}
static boolean hs_parse_real(
long expression_index)
{
boolean result = TRUE;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
char const *string = hs_compile_globals.compiled_source + expression->source_offset;
boolean decimal = FALSE;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x5D6,
expression->type==_hs_type_real);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x5D7,
expression->constant_type==expression->type);
if (*string == '-')
string++;
while (*string)
{
if (!isdigit(*string))
{
if (decimal || *string != '.')
{
hs_compile_globals.error = "this is not a valid real number.";
hs_compile_globals.error_offset = expression->source_offset;
result = FALSE;
break;
}
decimal = TRUE;
}
string++;
}
expression->real_value = (real)atof(
hs_compile_globals.compiled_source + expression->source_offset);
return result;
}
static boolean hs_parse_integer(
long expression_index)
{
boolean result = TRUE;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
char const *string = hs_compile_globals.compiled_source + expression->source_offset;
long value;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x5F7,
expression->type==_hs_type_short_integer || expression->type==_hs_type_long_integer);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x5F8,
expression->constant_type==expression->type);
if (*string == '-')
string++;
while (*string)
{
if (!isdigit(*string))
{
hs_compile_globals.error = "this is not a valid integer.";
hs_compile_globals.error_offset = expression->source_offset;
result = FALSE;
break;
}
string++;
}
value = atoi(hs_compile_globals.compiled_source + expression->source_offset);
if (result &&
expression->type != _hs_type_long_integer &&
(value > SHORT_MAX || value < SHORT_MIN))
{
hs_compile_globals.error = "shorts must be in the range [-32767, 32768].";
hs_compile_globals.error_offset = expression->source_offset;
result = FALSE;
}
if (expression->type == _hs_type_long_integer)
expression->data = value;
else
expression->short_value = (short)value;
return result;
}
static boolean hs_parse_string(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x61E,
expression->type==_hs_type_string);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x61F,
expression->constant_type==expression->type);
expression->data = (long)(hs_compile_globals.compiled_source + expression->source_offset);
return TRUE;
}
static boolean hs_parse_script(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
short script_index;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x62D,
expression->type==_hs_type_script);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x62E,
expression->constant_type==expression->type);
script_index = hs_find_script_by_name(
hs_compile_globals.compiled_source + expression->source_offset);
if (script_index != NONE)
{
expression->short_value = script_index;
return TRUE;
}
hs_compile_globals.error = "this is not a valid script name.";
hs_compile_globals.error_offset = expression->source_offset;
return FALSE;
}
static boolean hs_parse_tag_reference(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
struct scenario *scenario = global_scenario_get();
tag group_tag;
short reference_index;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x69E,
HS_TYPE_IS_TAG_REFERENCE(expression->type));
group_tag = hs_tag_reference_type_group_tags[expression->type - _hs_type_sound];
for (reference_index = 0;
reference_index < scenario->hs_references.count;
reference_index++)
{
struct hs_reference *reference = TAG_BLOCK_GET_ELEMENT(
&scenario->hs_references,
reference_index,
struct hs_reference);
if (csstrcmp(
reference->reference.name,
hs_compile_globals.compiled_source + expression->source_offset) == 0 &&
reference->reference.group_tag == group_tag)
{
expression->data = reference->reference.index;
break;
}
}
return TRUE;
}
static boolean hs_parse_enum(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
struct hs_enum_definition *enum_definition = &hs_enum_table[expression->type-_hs_type_enum_game_difficulty];
short value_index;
boolean result = TRUE;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x6BC,
HS_TYPE_IS_ENUM(expression->type));
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x6BD,
expression->constant_type==expression->type);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x6BE,
enum_definition->count);
for (value_index = 0; value_index < enum_definition->count; value_index++)
{
if (_stricmp(
hs_compile_globals.compiled_source + expression->source_offset,
enum_definition->values[value_index]) == 0)
{
break;
}
}
if (value_index == enum_definition->count)
{
sprintf(
hs_compile_globals.error_buffer,
"%s must be ",
hs_type_names[expression->type]);
for (value_index = 0; value_index < enum_definition->count - 1; value_index++)
{
csstrcat(hs_compile_globals.error_buffer, "\"");
csstrcat(hs_compile_globals.error_buffer, enum_definition->values[value_index]);
csstrcat(hs_compile_globals.error_buffer, "\", ");
}
if (enum_definition->count > 1)
csstrcat(hs_compile_globals.error_buffer, "or ");
csstrcat(hs_compile_globals.error_buffer, "\"");
csstrcat(hs_compile_globals.error_buffer, enum_definition->values[value_index]);
csstrcat(hs_compile_globals.error_buffer, "\".");
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = expression->source_offset;
result = FALSE;
}
expression->short_value = value_index;
return result;
}
static boolean hs_parse_scenario_datum(
long expression_index,
short offset,
struct tag_block *block,
long element_size)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
boolean result = FALSE;
short element_index;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x6F1,
element_size<=SHORT_MAX);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x6F2,
offset+TAG_STRING_LENGTH<element_size);
for (element_index = 0; element_index < block->count; element_index++)
{
char const *element = tag_block_get_element_with_size(
block,
element_index,
element_size);
if (_stricmp(
element + offset,
hs_compile_globals.compiled_source + expression->source_offset) == 0)
{
expression->data = element_index;
result = TRUE;
break;
}
}
if (!result)
{
sprintf(
hs_compile_globals.error_buffer,
"this is not a valid %s name",
hs_type_names[expression->type]);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = expression->source_offset;
}
return result;
}
static boolean hs_parse_trigger_volume(
long expression_index)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x711,
hs_syntax_get(expression_index)->type==_hs_type_trigger_volume);
return hs_parse_scenario_datum(
expression_index,
offsetof(struct scenario_trigger_volume, name),
&global_scenario_get()->trigger_volumes,
sizeof(struct scenario_trigger_volume));
}
static boolean hs_parse_cutscene_flag(
long expression_index)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x719,
hs_syntax_get(expression_index)->type==_hs_type_cutscene_flag);
return hs_parse_scenario_datum(
expression_index,
4,
&global_scenario_get()->cutscene_flags,
scenario_cutscene_flag_size);
}
static boolean hs_parse_cutscene_camera_point(
long expression_index)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x721,
hs_syntax_get(expression_index)->type==_hs_type_cutscene_camera_point);
return hs_parse_scenario_datum(
expression_index,
offsetof(struct scenario_cutscene_camera_point, name),
&global_scenario_get()->cutscene_camera_points,
sizeof(struct scenario_cutscene_camera_point));
}
static boolean hs_parse_cutscene_title(
long expression_index)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x729,
hs_syntax_get(expression_index)->type==_hs_type_cutscene_title);
return hs_parse_scenario_datum(
expression_index,
4,
&global_scenario_get()->cutscene_chapter_titles,
scenario_cutscene_title_size);
}
static boolean hs_parse_cutscene_recording(
long expression_index)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x731,
hs_syntax_get(expression_index)->type==_hs_type_cutscene_recording);
return hs_parse_scenario_datum(
expression_index,
0,
&global_scenario_get()->recorded_animations,
scenario_recorded_animation_size);
}
static boolean hs_parse_device_group(
long expression_index)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x739,
hs_syntax_get(expression_index)->type==_hs_type_device_group);
return hs_parse_scenario_datum(
expression_index,
0,
&global_scenario_get()->device_groups,
scenario_device_group_size);
}
static boolean hs_parse_ai(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
boolean result;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x744,
hs_syntax_get(expression_index)->type==_hs_type_ai);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x745,
expression->constant_type==expression->type);
result = ai_index_from_string(
global_scenario_get(),
hs_compile_globals.compiled_source + expression->source_offset,
&expression->data);
if (!result)
{
hs_compile_globals.error = "this is not a valid ai encounter or squad.";
hs_compile_globals.error_offset = expression->source_offset;
}
return result;
}
static boolean hs_parse_ai_command_list(
long expression_index)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x755,
hs_syntax_get(expression_index)->type==_hs_type_ai_command_list);
return hs_parse_scenario_datum(
expression_index,
0,
&global_scenario_get()->ai_command_lists,
scenario_ai_command_list_size);
}
static boolean hs_parse_starting_profile(
long expression_index)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x75D,
hs_syntax_get(expression_index)->type==_hs_type_starting_profile);
return hs_parse_scenario_datum(
expression_index,
0,
&global_scenario_get()->starting_profiles,
sizeof(struct scenario_starting_profile));
}
static boolean hs_parse_conversation(
long expression_index)
{
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x765,
hs_syntax_get(expression_index)->type==_hs_type_conversation);
return hs_parse_scenario_datum(
expression_index,
0,
&global_scenario_get()->ai_conversations,
scenario_conversation_size);
}
static boolean hs_parse_object_name(
long expression_index)
{
boolean result = FALSE;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
short object_name_index;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x771,
HS_TYPE_IS_OBJECT_NAME(expression->type));
object_name_index = scenario_object_name_index_from_string(
global_scenario_get(),
hs_compile_globals.compiled_source + expression->source_offset);
if (object_name_index != NONE)
{
struct scenario_object_name *object_name = TAG_BLOCK_GET_ELEMENT(
&global_scenario_get()->object_names,
object_name_index,
struct scenario_object_name);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x77A,
object_name->runtime_object_type!=NONE);
if (TEST_FLAG(
(short)hs_object_type_masks[expression->type - first_hs_object_name_type],
object_name->runtime_object_type))
{
expression->short_value = object_name_index;
result = TRUE;
}
else
{
sprintf(
hs_compile_globals.error_buffer,
"this is not an object of type %s.",
hs_type_names[expression->type]);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = expression->source_offset;
}
}
else
{
hs_compile_globals.error = "this is not a valid object name.";
hs_compile_globals.error_offset = expression->source_offset;
}
return result;
}
static boolean hs_parse_object(
long expression_index)
{
boolean result = TRUE;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x79A,
HS_TYPE_IS_OBJECT(expression->type));
if (csstrcmp(
hs_compile_globals.compiled_source + expression->source_offset,
"none") == 0)
{
expression->data = NONE;
}
else
{
expression->type += NUMBER_OF_HS_OBJECT_TYPES;
expression->constant_type = expression->type;
result = hs_parse_object_name(expression_index);
expression->type -= NUMBER_OF_HS_OBJECT_TYPES;
}
return result;
}
static boolean hs_parse_navpoint(
long expression_index)
{
boolean result = FALSE;
long hud_globals_index;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x7B1,
hs_syntax_get(expression_index)->type==_hs_type_navpoint);
hud_globals_index = interface_get_tag_index(_interface_hud_globals);
if (hud_globals_index != NONE)
{
struct hud_globals_definition *hud_globals;
hud_globals = hud_globals_definition_get(
interface_get_tag_index(_interface_hud_globals));
result = hs_parse_scenario_datum(
expression_index,
0,
&hud_globals->waypoint.arrows,
hud_waypoint_arrow_size);
}
return result;
}
static boolean hs_parse_hud_message(
long expression_index)
{
boolean result = FALSE;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x7BF,
hs_syntax_get(expression_index)->type==_hs_type_hud_message);
if (global_scenario_get()->hud_messages.index != NONE)
{
struct hud_message_text_definition *hud_messages;
hud_messages = hud_message_text_definition_get(
global_scenario_get()->hud_messages.index);
result = hs_parse_scenario_datum(
expression_index,
0,
&hud_messages->messages,
hud_message_definition_size);
}
return result;
}
static boolean hs_parse_object_list(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
boolean result;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x7CF,
expression->type==_hs_type_object_list);
expression->constant_type = first_hs_object_name_type;
expression->type = first_hs_object_name_type;
result = hs_parse_object_name(expression_index);
expression->type = _hs_type_object_list;
return result;
}
static short string_list_find(
char const *string,
short list_count,
char const **list)
{
short list_index;
for (list_index = 0; list_index < list_count; list_index++)
{
if (!strcmp(string, list[list_index]))
return list_index;
}
return NONE;
}
static long hs_concatenate_string_constant(
char const *string)
{
long result = hs_find_string_constant(string);
if (result == NONE)
{
short string_size = (short)(strlen(string) + 1);
if (string_size < hs_compile_globals.string_constant_buffer_size)
{
memcpy(
hs_compile_globals.string_constant_buffer + hs_compile_globals.string_constant_buffer_offset,
string,
string_size);
result = hs_compile_globals.string_constant_buffer_offset;
hs_compile_globals.string_constant_buffer_offset += string_size;
hs_compile_globals.string_constant_buffer_size -= string_size;
}
else
{
match_vassert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x264,
string_size<hs_compile_globals.string_constant_buffer_size,
"ran out of script string constant memory");
}
}
return result;
}
static boolean hs_add_global(
long expression_index)
{
boolean result = FALSE;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
long type_expression_index = hs_syntax_get(expression->data)->next_node_index;
long name_expression_index;
long value_expression_index;
if (type_expression_index != NONE
&& (name_expression_index = hs_syntax_get(type_expression_index)->next_node_index) != NONE
&& (value_expression_index = hs_syntax_get(name_expression_index)->next_node_index) != NONE
&& hs_syntax_get(value_expression_index)->next_node_index == NONE)
{
char const *type_name = hs_compile_globals.compiled_source + hs_syntax_get(type_expression_index)->source_offset;
short type = string_list_find(type_name, NUMBER_OF_HS_TYPES, hs_type_names);
if (!hs_type_valid(type))
{
hs_compile_globals.error = "this is not a valid type.";
hs_compile_globals.error_offset = hs_syntax_get(type_expression_index)->source_offset;
}
else
{
char const *global_name = hs_compile_globals.compiled_source + hs_syntax_get(name_expression_index)->source_offset;
if (strlen(global_name) > 0 && strlen(global_name) <= TAG_STRING_LENGTH)
{
if (hs_find_global_by_name(global_name) == NONE)
{
hs_compile_globals.disallow_blocks = TRUE;
hs_compile_globals.disallow_sets = TRUE;
if (hs_parse(value_expression_index, type))
{
short global_index = (short)tag_block_add_element(&global_scenario_get()->hs_globals);
if (global_index != NONE)
{
struct hs_global *global = TAG_BLOCK_GET_ELEMENT(
&global_scenario_get()->hs_globals,
global_index,
struct hs_global);
strcpy(global->name, global_name);
global->type = type;
global->initialization_expression_index = value_expression_index;
result = TRUE;
}
else
{
hs_compile_globals.error = "i couldn't allocate space for this global.";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
}
hs_compile_globals.disallow_blocks = FALSE;
hs_compile_globals.disallow_sets = FALSE;
}
else
{
hs_compile_globals.error = "there is already a variable by this name.";
hs_compile_globals.error_offset = hs_syntax_get(name_expression_index)->source_offset;
}
}
else
{
hs_compile_globals.error = "i expected a global variable name less than 32 characters.";
hs_compile_globals.error_offset = hs_syntax_get(name_expression_index)->source_offset;
}
}
}
else
{
hs_compile_globals.error = "i expected (global<type> <name> <initial value>)";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
return result;
}
static boolean hs_add_script(
long expression_index)
{
boolean result = FALSE;
long script_type_expression_index = hs_syntax_get(hs_syntax_get(expression_index)->data)->next_node_index;
if (script_type_expression_index != NONE)
{
struct hs_syntax_node *script_type_expression = hs_syntax_get(script_type_expression_index);
short script_type = string_list_find(
hs_compile_globals.compiled_source + script_type_expression->source_offset,
NUMBER_OF_HS_SCRIPT_TYPES,
hs_script_type_names);
if (script_type != NONE)
{
short return_type;
long name_expression_index = NONE;
long body_expression_index;
if (script_type == _hs_script_static || script_type == _hs_script_stub)
{
long return_type_expression_index = hs_syntax_get(script_type_expression_index)->next_node_index;
if (return_type_expression_index != NONE)
{
struct hs_syntax_node *return_type_expression = hs_syntax_get(return_type_expression_index);
return_type = string_list_find(
hs_compile_globals.compiled_source + return_type_expression->source_offset,
NUMBER_OF_HS_TYPES,
hs_type_names);
name_expression_index = hs_syntax_get(return_type_expression_index)->next_node_index;
if (hs_type_valid(return_type))
{
result = TRUE;
}
else
{
hs_compile_globals.error = "this is not a valid return type.";
hs_compile_globals.error_offset = hs_syntax_get(return_type_expression_index)->source_offset;
}
}
else
{
hs_compile_globals.error = "i expected (script local <type> <name> <expression(s)>).";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
}
else
{
return_type = _hs_type_void;
name_expression_index = hs_syntax_get(script_type_expression_index)->next_node_index;
result = TRUE;
}
if (result)
{
result = FALSE;
if (name_expression_index != NONE &&
(body_expression_index = hs_syntax_get(name_expression_index)->next_node_index) != NONE)
{
struct hs_syntax_node *name_expression = hs_syntax_get(name_expression_index);
char const *script_name = hs_compile_globals.compiled_source + name_expression->source_offset;
if (strlen(script_name) > 0 && strlen(script_name) <= TAG_STRING_LENGTH)
{
struct scenario *scenario = global_scenario_get();
long script_index = hs_find_script_by_name(script_name);
if (script_index == NONE)
{
script_index = tag_block_add_element(&scenario->hs_scripts);
if (script_index == NONE)
{
hs_compile_globals.error = "i couldn't allocate a script.";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
}
else
{
struct hs_script *existing_script = TAG_BLOCK_GET_ELEMENT(
&scenario->hs_scripts,
script_index,
struct hs_script);
if (existing_script->script_type != _hs_script_stub ||
existing_script->return_type != return_type ||
script_type != _hs_script_static)
{
if (existing_script->script_type == _hs_script_static &&
existing_script->return_type == return_type &&
script_type == _hs_script_stub)
{
/* the static script already replaced this stub */
result = TRUE;
}
else
{
hs_compile_globals.error = "only static scripts of the same type can override stub scripts.";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
script_index = NONE;
}
}
if (script_index != NONE)
{
struct hs_script *script = TAG_BLOCK_GET_ELEMENT(
&scenario->hs_scripts,
script_index,
struct hs_script);
long root_expression_index = datum_new(hs_syntax_data);
long begin_expression_index = datum_new(hs_syntax_data);
if (root_expression_index != NONE && begin_expression_index != NONE)
{
struct hs_syntax_node *root_expression = hs_syntax_get(root_expression_index);
struct hs_syntax_node *begin_expression = hs_syntax_get(begin_expression_index);
root_expression->data = begin_expression_index;
root_expression->next_node_index = NONE;
root_expression->source_offset = hs_syntax_get(expression_index)->source_offset;
root_expression->flags = 0;
begin_expression->next_node_index = body_expression_index;
begin_expression->source_offset = NONE;
begin_expression->function_index = _hs_function_begin;
begin_expression->flags = FLAG(_hs_syntax_node_primitive_bit);
begin_expression->type = _hs_function_name;
if (hs_parse(root_expression_index, return_type))
{
strcpy(script->name, script_name);
script->return_type = return_type;
script->script_type = script_type;
script->root_expression_index = root_expression_index;
result = TRUE;
}
}
else
{
hs_compile_globals.error = "i couldn't allocate a syntax node.";
}
}
}
else
{
hs_compile_globals.error = "i expected a script name less than 32 characters.";
hs_compile_globals.error_offset = hs_syntax_get(name_expression_index)->source_offset;
}
}
else
{
if (script_type == _hs_script_static)
hs_compile_globals.error = "i expected (script static <type> <name> <expression(s)>)";
else if (script_type == _hs_script_stub)
hs_compile_globals.error = "i expected (script stub <type> <name> <expression(s)>)";
else
hs_compile_globals.error = "i expected (script <type> <name> <expression(s)>)";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
}
}
else
{
hs_compile_globals.error = "script type must be \"startup\", \"dormant\", \"continuous\", or \"static\".";
hs_compile_globals.error_offset = hs_syntax_get(script_type_expression_index)->source_offset;
}
}
else
{
hs_compile_globals.error = "i expected (script <type> <name> <expression(s)>)";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
return result;
}
static void hs_tokenize_primitive(
struct hs_tokenizer *tokenizer,
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
char *token_start = tokenizer->cursor;
char character;
if (*token_start == '"')
{
tokenizer->cursor = token_start + 1;
expression->source_offset = tokenizer->cursor - hs_compile_globals.compiled_source;
while (*tokenizer->cursor && *tokenizer->cursor != '"')
tokenizer->cursor++;
if (!*tokenizer->cursor)
{
hs_compile_globals.error = "this quoted constant is unterminated.";
hs_compile_globals.error_offset = expression->source_offset - 1;
}
*tokenizer->cursor = 0;
tokenizer->cursor++;
}
else
{
expression->source_offset = token_start - hs_compile_globals.compiled_source;
while (*tokenizer->cursor)
{
char *position = tokenizer->cursor;
character = *position;
if (character == ')' || character == ';')
break;
if (character_in_list(character, NUMBEROF(whitespace_characters), whitespace_characters) ||
character_in_list(character, NUMBEROF(eol_characters), eol_characters))
{
break;
}
tokenizer->cursor = position + 1;
}
}
strlwr(hs_compile_globals.compiled_source + expression->source_offset);
return;
}
static boolean hs_parse_primitive(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
boolean result = FALSE;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x4AF,
hs_type_valid(expression->type) || expression->type==_hs_special_form || expression->type==_hs_unparsed);
if (expression->type == _hs_special_form)
{
hs_compile_globals.error = "i expected a script or variable definition.";
hs_compile_globals.error_offset = expression->source_offset;
}
else if (expression->type == _hs_type_void)
{
hs_compile_globals.error = "the value of this expression (in a <void> slot) can never be used.";
hs_compile_globals.error_offset = expression->source_offset;
}
else
{
if (!hs_compile_globals.variables_predetermined ||
TEST_FLAG(expression->flags, _hs_syntax_node_variable_bit))
{
result = hs_parse_variable(expression_index);
}
if (!result &&
expression->type &&
!hs_compile_globals.error &&
(!hs_compile_globals.variables_predetermined ||
!TEST_FLAG(expression->flags, _hs_syntax_node_variable_bit)))
{
hs_primitive_parser parser = hs_type_primitive_parsers[expression->type];
if (parser)
{
return parser(expression_index);
}
else
{
sprintf(
hs_compile_globals.error_buffer,
"expressions of type %s are currently unsupported.",
hs_type_names[expression->type]);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = expression->source_offset;
return FALSE;
}
}
}
return result;
}
static boolean hs_parse_nonprimitive(
long expression_index)
{
boolean result = FALSE;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
long predicate_index = hs_syntax_get(expression_index)->data;
struct hs_syntax_node *predicate = hs_syntax_get(predicate_index);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x534,
hs_type_valid(expression->type) || expression->type==_hs_special_form || expression->type==_hs_unparsed);
if (TEST_FLAG(hs_syntax_get(predicate_index)->flags, _hs_syntax_node_primitive_bit))
{
if (expression->type == _hs_special_form)
{
if (!strcmp(hs_compile_globals.compiled_source + predicate->source_offset, "global"))
{
result = hs_add_global(expression_index);
}
else if (!strcmp(hs_compile_globals.compiled_source + predicate->source_offset, "script"))
{
result = hs_add_script(expression_index);
}
else
{
hs_compile_globals.error = "i expected \"script\" or \"global\".";
hs_compile_globals.error_offset = predicate->source_offset;
}
}
else
{
hs_parse_call_predicate(expression_index);
if (expression->function_index != NONE)
{
if (TEST_FLAG(expression->flags, _hs_syntax_node_script_bit))
{
struct hs_script *script = TAG_BLOCK_GET_ELEMENT(
&global_scenario_get()->hs_scripts,
expression->function_index,
struct hs_script);
if (script->script_type != _hs_script_static && script->script_type != _hs_script_stub)
{
hs_compile_globals.error = "this is not a static script.";
hs_compile_globals.error_offset = expression->source_offset;
}
else if (expression->type && !hs_can_cast(script->return_type, expression->type))
{
sprintf(
hs_compile_globals.error_buffer,
"i expected a %s, but this script returns a %s.",
hs_type_names[expression->type],
hs_type_names[script->return_type]);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = expression->source_offset;
}
else
{
if (!expression->type)
expression->type = script->return_type;
result = TRUE;
}
}
else
{
struct hs_function_definition *function = hs_function_get(expression->function_index);
if (expression->type && !hs_can_cast(function->return_type, expression->type))
{
sprintf(
hs_compile_globals.error_buffer,
"i expected a %s, but this function returns a %s.",
hs_type_names[expression->type],
hs_type_names[function->return_type]);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = expression->source_offset;
}
else if (hs_compile_globals.disallow_blocks &&
(expression->function_index == _hs_function_sleep || expression->function_index == _hs_function_sleep_until))
{
hs_compile_globals.error = "it is illegal to block in this context.";
hs_compile_globals.error_offset = expression->source_offset;
}
else if (hs_compile_globals.disallow_sets && expression->function_index == _hs_function_set)
{
hs_compile_globals.error = "it is illegal to set the value of variables in this context.";
hs_compile_globals.error_offset = expression->source_offset;
}
else
{
if (!expression->type && function->return_type != _hs_passthrough)
expression->type = function->return_type;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x58C,
function->parse);
result = function->parse(expression->function_index, expression_index);
}
}
}
else
{
hs_compile_globals.error = "this is not a valid function or script name.";
hs_compile_globals.error_offset = predicate->source_offset;
}
}
}
else
{
char const *expected_name = expression->type == _hs_special_form ?
"\"script\" or \"global\"" :
"a function name";
sprintf(
hs_compile_globals.error_buffer,
"i expected %s, but i got an expression.",
expected_name);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = predicate->source_offset;
}
return result;
}
boolean hs_compile_postprocess(
char const **error_message_pointer,
char const **error_source_pointer)
{
boolean success = TRUE;
long expression_index;
short resolved_type;
struct hs_script *script;
hs_compile_globals.compiled_source = global_scenario_get()->hs_string_constants.address;
hs_compile_globals.compiled_source_size =
global_scenario_get()->hs_string_constants.size - HS_MAXIMUM_DYNAMIC_SOURCE_DATA_BYTES;
hs_compile_globals.error = NULL;
hs_compile_globals.variables_predetermined = TRUE;
*error_message_pointer = NULL;
*error_source_pointer = NULL;
for (expression_index = data_next_index(hs_syntax_data, NONE);
success && expression_index != NONE;
expression_index = data_next_index(hs_syntax_data, expression_index))
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
if (hs_type_valid(expression->type))
{
if (TEST_FLAG(hs_syntax_get(expression_index)->flags, _hs_syntax_node_primitive_bit))
{
if (expression->type >= _hs_type_string ||
TEST_FLAG(expression->flags, _hs_syntax_node_variable_bit))
{
success = hs_verify_source_offset(expression->source_offset);
if (success)
success = hs_parse_primitive(expression_index);
}
if (success && TEST_FLAG(expression->flags, _hs_syntax_node_variable_bit))
resolved_type = hs_global_get_type((short)expression->data);
else
resolved_type = expression->constant_type;
}
else if (TEST_FLAG(expression->flags, _hs_syntax_node_script_bit))
{
if (expression->script_index >= 0 &&
expression->script_index < global_scenario_get()->hs_scripts.count &&
((script = TAG_BLOCK_GET_ELEMENT(
&global_scenario_get()->hs_scripts,
expression->script_index,
struct hs_script))->script_type == _hs_script_static ||
script->script_type == _hs_script_stub))
{
resolved_type = script->return_type;
}
else
{
hs_compile_globals.error = "bad script index (you need to recompile.)";
success = FALSE;
}
}
else
{
long predicate_index = hs_syntax_get(expression_index)->data;
struct hs_syntax_node *predicate;
if (predicate_index == NONE ||
(predicate = hs_syntax_get(predicate_index))->type != _hs_function_name)
{
hs_compile_globals.error = "corrupt syntax tree (you need to recompile scripts.)";
success = FALSE;
}
else if (hs_verify_source_offset(predicate->source_offset))
{
short function_index = hs_find_function_by_name(
hs_compile_globals.compiled_source + predicate->source_offset);
if (function_index != NONE)
{
expression->function_index = function_index;
resolved_type = hs_function_get(expression->function_index)->return_type;
}
else
{
hs_compile_globals.error = "missing function (you need to recompile scripts.)";
success = FALSE;
}
}
else
{
success = FALSE;
}
}
if (success)
{
if ((!hs_type_valid(resolved_type) && resolved_type != _hs_passthrough) ||
!hs_can_cast(resolved_type, expression->type))
{
hs_compile_globals.error = "type is inconsistent with usage (you need to recompile scripts.)";
success = FALSE;
}
else
{
success = TRUE;
}
}
}
else if (expression->type != _hs_function_name)
{
hs_compile_globals.error = "missing type (you need to recompile scripts.)";
success = FALSE;
}
}
if (!success)
{
*error_message_pointer = hs_compile_globals.error;
if (hs_compile_globals.error_offset != NONE)
*error_source_pointer = hs_compile_globals.compiled_source + hs_compile_globals.error_offset;
}
hs_compile_globals.compiled_source = NULL;
hs_compile_globals.error = NULL;
hs_compile_globals.variables_predetermined = FALSE;
return success;
}
static void hs_concatenate_expression(
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
SET_FLAG(expression->flags, _hs_syntax_node_permanent_bit, TRUE);
if (TEST_FLAG(hs_syntax_get(expression_index)->flags, _hs_syntax_node_primitive_bit))
{
if (expression->type == _hs_function_name)
{
if (expression->source_offset != NONE)
{
expression->source_offset = hs_concatenate_string_constant(
hs_compile_globals.compiled_source + expression->source_offset);
}
else
{
expression->source_offset = hs_concatenate_string_constant(
hs_function_get(expression->function_index)->name);
}
}
else if (TEST_FLAG(expression->flags, _hs_syntax_node_variable_bit) || expression->type >= _hs_type_string)
{
expression->source_offset = hs_concatenate_string_constant(
hs_compile_globals.compiled_source + expression->source_offset);
}
}
else
{
long child_expression_index;
for (child_expression_index = expression->data;
child_expression_index != NONE;
child_expression_index = hs_syntax_get(child_expression_index)->next_node_index)
{
hs_concatenate_expression(child_expression_index);
}
}
return;
}
static long hs_tokenize(
struct hs_tokenizer *tokenizer)
{
long expression_index = datum_new(hs_syntax_data);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x39E,
!hs_compile_globals.error);
if (expression_index != NONE)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
expression->flags = 0;
expression->type = _hs_unparsed;
expression->function_index = NONE;
expression->next_node_index = NONE;
expression->flags = *tokenizer->cursor != '(';
if (TEST_FLAG(hs_syntax_get(expression_index)->flags, _hs_syntax_node_primitive_bit))
hs_tokenize_primitive(tokenizer, expression_index);
else
hs_tokenize_nonprimitive(tokenizer, expression_index);
}
else
{
hs_compile_globals.error = "i couldn't allocate a syntax node.";
}
return expression_index;
}
static void hs_tokenize_nonprimitive(
struct hs_tokenizer *tokenizer,
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
long *child_link = &expression->data;
expression->source_offset = tokenizer->cursor - hs_compile_globals.compiled_source;
tokenizer->cursor++;
if (!hs_compile_globals.error)
{
do
{
char *token_start = tokenizer->cursor;
long child_index;
skip_whitespace(&tokenizer->cursor);
if (tokenizer->cursor != token_start)
*token_start = 0;
if (!*tokenizer->cursor)
{
hs_compile_globals.error = "this left parenthesis is unmatched.";
hs_compile_globals.error_offset = expression->source_offset;
break;
}
if (*tokenizer->cursor == ')')
{
*tokenizer->cursor = 0;
tokenizer->cursor++;
break;
}
child_index = hs_tokenize(tokenizer);
*child_link = child_index;
if (child_index != NONE)
child_link = &hs_syntax_get(child_index)->next_node_index;
}
while (!hs_compile_globals.error);
}
if (child_link == &expression->data && !hs_compile_globals.error)
{
hs_compile_globals.error = "this expression is empty.";
hs_compile_globals.error_offset = expression->source_offset;
}
return;
}
static void skip_whitespace(
char **cursor)
{
short state = _hs_tokenizer_state_normal;
char *position;
char character;
do
{
switch (state)
{
case _hs_tokenizer_state_normal:
position = *cursor;
character = *position;
if (character == ';')
{
*cursor = position + 1;
state = _hs_tokenizer_state_line_comment;
if (position[1] == '*')
{
state = _hs_tokenizer_state_block_comment;
(*cursor)++;
}
break;
}
if (character_in_list(character, NUMBEROF(whitespace_characters), whitespace_characters) ||
character_in_list(character, NUMBEROF(eol_characters), eol_characters))
{
goto skip_character;
}
return;
case _hs_tokenizer_state_line_comment:
position = *cursor;
if (!*position)
return;
if (character_in_list(*position, NUMBEROF(eol_characters), eol_characters))
state = _hs_tokenizer_state_normal;
goto skip_character;
case _hs_tokenizer_state_block_comment:
position = *cursor;
if (!*position)
{
hs_compile_globals.error = "unterminated comment.";
return;
}
if (*position == '*' && position[1] == ';')
{
state = _hs_tokenizer_state_normal;
*cursor = position + 1;
}
(*cursor)++;
break;
default:
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x46C,
!"unreachable");
break;
}
continue;
skip_character:
*cursor = position + 1;
}
while (state != _hs_tokenizer_state_done);
return;
}
boolean hs_parse(
long expression_index,
short expected_type)
{
boolean result = TRUE;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x48E,
!hs_compile_globals.error);
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x491,
hs_type_valid(expected_type) || expected_type==_hs_special_form || expected_type==_hs_unparsed);
if (!expression->type)
{
expression->type = expected_type;
if (TEST_FLAG(hs_syntax_get(expression_index)->flags, _hs_syntax_node_primitive_bit))
{
expression->constant_type = expected_type;
result = hs_parse_primitive(expression_index);
}
else
{
result = hs_parse_nonprimitive(expression_index);
}
}
return result;
}
boolean hs_macro_function_parse(
short function_index,
long expression_index)
{
boolean result = TRUE;
struct hs_function_definition *definition = hs_function_get(function_index);
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
long argument_expression_index = hs_syntax_get(expression->data)->next_node_index;
short parameter_index;
match_assert(
"c:\\halo\\SOURCE\\hs\\hs_compile.c",
0x819,
hs_type_valid(definition->return_type));
for (parameter_index = 0;
result && parameter_index < definition->parameter_count && argument_expression_index != NONE;
parameter_index++)
{
if (hs_parse(argument_expression_index, definition->parameter_types[parameter_index]))
{
struct hs_syntax_node *argument = hs_syntax_get(argument_expression_index);
argument_expression_index = argument->next_node_index;
}
else
{
result = FALSE;
}
}
if (result &&
(parameter_index != definition->parameter_count || argument_expression_index != NONE))
{
sprintf(
hs_compile_globals.error_buffer,
"the \"%s\" call requires exactly %d arguments.",
definition->name,
definition->parameter_count);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
result = FALSE;
}
return result;
}
boolean hs_parse_begin(
short function_index,
long expression_index)
{
boolean result = TRUE;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
long argument_expression_index = hs_syntax_get(
hs_syntax_get(expression_index)->data)->next_node_index;
long next_expression_index;
short argument_count;
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x15,
function_index==_hs_function_begin || function_index==_hs_function_begin_random);
for (argument_count = 0;
result && argument_expression_index != NONE;
argument_expression_index = next_expression_index, argument_count++)
{
next_expression_index = hs_syntax_get(argument_expression_index)->next_node_index;
if (function_index == _hs_function_begin)
{
short expected_type;
if (next_expression_index == NONE)
expected_type = expression->type;
else
expected_type = _hs_type_void;
result = hs_parse(argument_expression_index, expected_type);
if (next_expression_index == NONE && !expression->type && result)
expression->type = hs_syntax_get(argument_expression_index)->type;
}
else
{
result = hs_parse(argument_expression_index, expression->type);
if (!expression->type && result)
expression->type = hs_syntax_get(argument_expression_index)->type;
}
}
if (result)
{
if (argument_count < 1)
{
/* BUG (preserved for exact matching): January passes the function name
* although this format has no conversion for it; the argument is ignored. */
sprintf(
hs_compile_globals.error_buffer,
"a statement block must contain at least one argument.",
hs_function_get(function_index)->name);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
result = FALSE;
}
else if (argument_count > MAXIMUM_HS_BEGIN_RANDOM_ARGUMENTS &&
function_index == _hs_function_begin_random)
{
hs_compile_globals.error = "begin_random can take a maximum of 32 arguments (matt can increase this.)";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
result = FALSE;
}
}
return result;
}
boolean hs_parse_if(
short function_index,
long expression_index)
{
boolean result = FALSE;
boolean valid = FALSE;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
long condition_expression_index = hs_syntax_get(
hs_syntax_get(expression_index)->data)->next_node_index;
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x5B,
function_index==_hs_function_if);
if (condition_expression_index != NONE)
{
long then_expression_index = hs_syntax_get(condition_expression_index)->next_node_index;
if (then_expression_index != NONE)
{
long else_expression_index = hs_syntax_get(then_expression_index)->next_node_index;
if (else_expression_index == NONE ||
hs_syntax_get(else_expression_index)->next_node_index == NONE)
{
valid = TRUE;
if (hs_parse(condition_expression_index, _hs_type_boolean))
{
if (hs_parse(then_expression_index, expression->type))
{
if (!expression->type)
expression->type = hs_syntax_get(then_expression_index)->type;
result = else_expression_index == NONE ||
hs_parse(else_expression_index, expression->type);
}
else if (!hs_compile_globals.error &&
!expression->type &&
else_expression_index != NONE &&
hs_parse(else_expression_index, expression->type))
{
expression->type = hs_syntax_get(else_expression_index)->type;
result = hs_parse(then_expression_index, expression->type);
}
}
}
}
}
if (!valid)
{
hs_compile_globals.error = "i expected (if <condition> <then> [<else>]).";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
return result;
}
boolean hs_parse_cond(
short function_index,
long expression_index)
{
boolean result = FALSE;
long new_expression_index = hs_parse_cond_recursive(
expression_index,
hs_syntax_get(hs_syntax_get(expression_index)->data)->next_node_index);
if (new_expression_index != NONE)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
struct hs_syntax_node *new_expression = hs_syntax_get(new_expression_index);
short datum_header = expression->datum_header;
short type = expression->type;
new_expression->next_node_index = expression->next_node_index;
*expression = *new_expression;
expression->datum_header = datum_header;
result = hs_parse(expression_index, type);
}
return result;
}
boolean hs_parse_set(
short function_index,
long expression_index)
{
boolean result = FALSE;
long variable_expression_index = hs_syntax_get(
hs_syntax_get(expression_index)->data)->next_node_index;
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
if (variable_expression_index != NONE)
{
long value_expression_index = hs_syntax_get(variable_expression_index)->next_node_index;
if (value_expression_index != NONE)
{
if (hs_syntax_get(value_expression_index)->next_node_index == NONE)
{
struct hs_syntax_node *variable_expression = hs_syntax_get(variable_expression_index);
short global_index = hs_find_global_by_name(
hs_compile_globals.compiled_source + variable_expression->source_offset);
if (global_index != NONE)
{
short global_type = hs_global_get_type(global_index);
variable_expression->type = global_type;
if (expression->type && !hs_can_cast(global_type, expression->type))
{
sprintf(
hs_compile_globals.error_buffer,
"you cannot pass the result of this set (type %s) to a function that expects type %s.",
hs_type_names[variable_expression->type],
hs_type_names[hs_syntax_get(expression_index)->type]);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
else
{
match_vassert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x126,
hs_parse_variable(variable_expression_index),
"asserted");
if (!expression->type)
expression->type = variable_expression->type;
if (hs_parse(value_expression_index, variable_expression->type))
result = TRUE;
}
}
else
{
hs_compile_globals.error = "this is not a valid global variable.";
hs_compile_globals.error_offset = variable_expression->source_offset;
}
}
else
{
hs_compile_globals.error = "i didn't expect this argument.";
hs_compile_globals.error_offset = hs_syntax_get(
hs_syntax_get(value_expression_index)->next_node_index)->source_offset;
}
}
else
{
hs_compile_globals.error = "i expected an assignment value.";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
}
else
{
hs_compile_globals.error = "i expected a variable to set and a value.";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
return result;
}
boolean hs_parse_logical(
short function_index,
long expression_index)
{
boolean result = TRUE;
long argument_expression_index = hs_syntax_get(
hs_syntax_get(expression_index)->data)->next_node_index;
short argument_count;
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x15D,
function_index==_hs_function_and || function_index==_hs_function_or);
for (argument_count = 0;
result && argument_expression_index != NONE;
argument_count++)
{
result = hs_parse(argument_expression_index, _hs_type_boolean);
argument_expression_index = hs_syntax_get(argument_expression_index)->next_node_index;
}
if (result && argument_count < 2)
{
sprintf(
hs_compile_globals.error_buffer,
"the %s call requires at least 2 arguments.",
hs_function_get(function_index)->name);
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
result = FALSE;
}
return result;
}
boolean hs_parse_arithmetic(
short function_index,
long expression_index)
{
boolean result = TRUE;
long argument_expression_index = hs_syntax_get(
hs_syntax_get(expression_index)->data)->next_node_index;
short argument_count;
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x17D,
function_index>=_hs_function_plus && function_index<=_hs_function_max);
for (argument_count = 0;
result && argument_expression_index != NONE;
argument_count++)
{
result = hs_parse(argument_expression_index, _hs_type_real);
argument_expression_index = hs_syntax_get(argument_expression_index)->next_node_index;
}
if ((result && argument_count < 2) ||
(function_index == _hs_function_divide && argument_count > 2))
{
sprintf(
hs_compile_globals.error_buffer,
"the %s call requires %s2 arguments.",
hs_function_get(function_index)->name,
function_index == _hs_function_divide ? "" : "at least ");
hs_compile_globals.error = hs_compile_globals.error_buffer;
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
result = FALSE;
}
return result;
}
boolean hs_parse_equality(
short function_index,
long expression_index)
{
boolean result = FALSE;
long argument_indices[2];
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x1BC,
function_index==_hs_function_equal || function_index==_hs_function_not_equal);
if (hs_get_parameter_indices(
hs_function_get(function_index)->name,
2,
argument_indices,
expression_index))
{
if (hs_parse(argument_indices[0], _hs_unparsed))
{
if (hs_parse(argument_indices[1], hs_syntax_get(argument_indices[0])->type))
result = TRUE;
}
else if (!hs_compile_globals.error)
{
if (hs_parse(argument_indices[1], _hs_unparsed))
{
if (hs_parse(argument_indices[0], hs_syntax_get(argument_indices[1])->type))
result = TRUE;
}
else if (!hs_compile_globals.error)
{
if (hs_parse(argument_indices[0], _hs_type_real) &&
hs_parse(argument_indices[1], _hs_type_real))
result = TRUE;
}
}
}
return result;
}
boolean hs_parse_inequality(
short function_index,
long expression_index)
{
boolean result = FALSE;
long argument_indices[2];
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x1E3,
function_index>=_hs_function_gt && function_index<=_hs_function_lte);
if (hs_get_parameter_indices(
hs_function_get(function_index)->name,
2,
argument_indices,
expression_index))
{
if (hs_parse(argument_indices[0], _hs_unparsed) &&
(HS_TYPE_IS_ENUM(hs_syntax_get(argument_indices[0])->type) ||
(hs_syntax_get(argument_indices[0])->type>=_hs_type_real &&
hs_syntax_get(argument_indices[0])->type<=_hs_type_long_integer)))
{
if (hs_parse(argument_indices[1], hs_syntax_get(argument_indices[0])->type))
result = TRUE;
}
else if (!hs_compile_globals.error)
{
if (hs_parse(argument_indices[1], _hs_unparsed) &&
(HS_TYPE_IS_ENUM(hs_syntax_get(argument_indices[1])->type) ||
(hs_syntax_get(argument_indices[1])->type>=_hs_type_real &&
hs_syntax_get(argument_indices[1])->type<=_hs_type_long_integer)))
{
if (hs_parse(argument_indices[0], hs_syntax_get(argument_indices[1])->type))
result = TRUE;
}
else if (!hs_compile_globals.error)
{
if (hs_parse(argument_indices[0], _hs_type_real) &&
hs_parse(argument_indices[1], _hs_type_real))
result = TRUE;
}
}
}
return result;
}
boolean hs_parse_sleep(
short function_index,
long expression_index)
{
boolean result = FALSE;
long ticks_expression_index = hs_syntax_get(
hs_syntax_get(expression_index)->data)->next_node_index;
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x20E,
function_index==_hs_function_sleep);
if (ticks_expression_index != NONE)
{
if (hs_parse(ticks_expression_index, _hs_type_short_integer))
{
long script_expression_index = hs_syntax_get(ticks_expression_index)->next_node_index;
if (script_expression_index == NONE || hs_parse(script_expression_index, _hs_type_script))
result = TRUE;
}
}
else
{
hs_compile_globals.error = "the sleep call requires a time and, optionally, a script name.";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
return result;
}
boolean hs_parse_sleep_until(
short function_index,
long expression_index)
{
boolean result = FALSE;
long condition_expression_index;
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x235,
function_index==_hs_function_sleep_until);
condition_expression_index = hs_syntax_get(
hs_syntax_get(expression_index)->data)->next_node_index;
if (condition_expression_index != NONE)
{
long period_expression_index = hs_syntax_get(condition_expression_index)->next_node_index;
result = hs_parse(condition_expression_index, _hs_type_boolean);
if (result && period_expression_index != NONE)
{
long timeout_expression_index = hs_syntax_get(period_expression_index)->next_node_index;
result = hs_parse(period_expression_index, _hs_type_short_integer);
if (result && timeout_expression_index != NONE)
result = hs_parse(timeout_expression_index, _hs_type_long_integer);
}
}
else
{
hs_compile_globals.error = "the sleep_until call requires a condition and, optionally, a period.";
hs_compile_globals.error_offset = hs_syntax_get(expression_index)->source_offset;
}
return result;
}
boolean hs_parse_wake(
short function_index,
long expression_index)
{
boolean result = FALSE;
long script_expression_index;
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x25D,
function_index==_hs_function_wake);
if (hs_get_parameter_indices(
hs_function_get(function_index)->name,
1,
&script_expression_index,
expression_index))
{
struct hs_syntax_node *script_expression = hs_syntax_get(script_expression_index);
if (hs_parse(script_expression_index, _hs_type_script))
{
struct hs_script *script = TAG_BLOCK_GET_ELEMENT(
&global_scenario_get()->hs_scripts,
script_expression->short_value,
struct hs_script);
if (script->script_type == _hs_script_static || script->script_type == _hs_script_stub)
{
hs_compile_globals.error = "this static script cannot be awakened.";
hs_compile_globals.error_offset = script_expression->source_offset;
}
else
{
result = TRUE;
}
}
}
return result;
}
boolean hs_parse_inspect(
short function_index,
long expression_index)
{
struct hs_syntax_node *expression = hs_syntax_get(expression_index);
boolean result = FALSE;
long argument_expression_index;
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x27F,
function_index==_hs_function_inspect);
if (hs_get_parameter_indices(
hs_function_get(function_index)->name,
1,
&argument_expression_index,
expression_index))
{
struct hs_syntax_node *argument_expression = hs_syntax_get(argument_expression_index);
if (hs_parse(argument_expression_index, _hs_unparsed))
{
result = TRUE;
}
else if (!hs_compile_globals.error)
{
hs_compile_globals.error = "this is not a global variable reference, function call, or script call.";
hs_compile_globals.error_offset = argument_expression->source_offset;
}
}
return result;
}
boolean hs_parse_object_cast_up(
short function_index,
long expression_index)
{
boolean result = FALSE;
long argument_indices[1];
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x29A,
function_index>=_hs_function_object_to_unit && function_index<=_hs_function_object_to_unit);
if (hs_get_parameter_indices(
hs_function_get(function_index)->name,
1,
argument_indices,
expression_index))
{
result = hs_parse(argument_indices[0], _hs_type_object);
}
return result;
}
boolean hs_parse_debug_string(
short function_index,
long expression_index)
{
boolean result = TRUE;
long argument_expression_index = hs_syntax_get(
hs_syntax_get(expression_index)->data)->next_node_index;
match_assert(
"c:\\halo\\source\\hs\\hs_library_internal_compile.h",
0x2AE,
(function_index>=_hs_function_debug_string__first) && (function_index<=_hs_function_debug_string__last));
while (result && argument_expression_index != NONE)
{
result = hs_parse(argument_expression_index, _hs_type_string);
argument_expression_index = hs_syntax_get(argument_expression_index)->next_node_index;
}
return result;
}