scripts: Big update to the scripts lexer, parser and compilers.

Supports most syscalls, functions and opcodes. Includes a few bug fixes.
This commit is contained in:
Loïc Hoguin 2010-12-11 14:38:13 +01:00
parent 8504352ef7
commit c161f8c48a
3 changed files with 635 additions and 81 deletions

View File

@ -32,71 +32,166 @@ root(Routines) ->
root(Routines, 0, [], []).
root(nil, _Pos, Funcs, Acc) ->
{iolist_to_binary(lists:reverse(Acc)), Funcs};
root({{external, Name}, Next}, Pos, Funcs, Acc) ->
root(Next, Pos, [Name|Funcs], Acc);
root({Routine, Next}, Pos, Funcs, Acc) ->
{Bin, Funcs2} = routine(Routine, Funcs),
Pos2 = case Next of nil -> 0; _ -> Pos + byte_size(Bin) + 4 end,
root(Next, Pos2, Funcs2, [<< Pos2:32/little, Bin/binary >>|Acc]).
routine({Type, Name, Instrs}, Funcs) ->
{TypeBin, Funcs2} = case Type of
event -> {<< $E, $V, $E, $N, $T, $. >>, Funcs};
function -> {<< >>, [Name|Funcs]}
end,
NameBin = list_to_binary(Name),
Padding = 8 * (32 - byte_size(TypeBin) - byte_size(NameBin)),
{_Inc, InstrsBin, VarsList} = instructions(Instrs, Funcs),
routine({event_def, {Name, _Type}, Instrs}, Funcs) ->
NameBin = routine_name_to_binary([$E, $V, $E, $N, $T, $.|Name]),
{BodyBin, Funcs2} = routine_body_to_binary(Instrs, Funcs),
{<< NameBin/binary, BodyBin/binary >>, Funcs2};
routine({function_def, {Name, _Type}, Instrs}, Funcs) ->
NameBin = routine_name_to_binary(Name),
{BodyBin, Funcs2} = routine_body_to_binary(Instrs, Funcs),
{<< NameBin/binary, BodyBin/binary >>, [Name|Funcs2]};
routine({num_var, {Name, _Type}}, Funcs) ->
NameBin = routine_name_to_binary(Name),
{<< NameBin/binary, 0:32/little, 16#3c:32/little, 0:32 >>, [Name|Funcs]};
routine({str_var, {Name, _Type}, Length}, Funcs) ->
NameBin = routine_name_to_binary(Name),
{<< NameBin/binary, 0:32/little, 16#49:32/little, Length:32/little >>, [Name|Funcs]}.
routine_body_to_binary(Instrs, Funcs) ->
{_Inc, InstrsBin, VarsList, Funcs2} = instructions(Instrs, Funcs),
InstrsSize = byte_size(InstrsBin) + 4,
NbVars = length(VarsList),
VarsBin = iolist_to_binary([<< VarN:32/little, VarPos:32/little >> || {VarN, VarPos} <- VarsList]),
{<< TypeBin/binary, NameBin/binary, 0:Padding, InstrsSize:32/little,
76:32/little, NbVars:32/little, InstrsBin/binary, 0:32, VarsBin/binary >>, Funcs2}.
{<< InstrsSize:32/little, 16#4c:32/little, NbVars:32/little, InstrsBin/binary, 0:32, VarsBin/binary >>, Funcs2}.
routine_name_to_binary(Name) ->
NameBin = list_to_binary(Name),
Padding = 8 * (32 - byte_size(NameBin)),
<< NameBin/binary, 0:Padding >>.
instructions(Instrs, Funcs) ->
instructions(Instrs, Funcs, 0, [], []).
instructions(Instrs, Funcs, Pos) ->
instructions(Instrs, Funcs, Pos, [], []).
instructions(nil, _Funcs, Pos, Acc, VarsAcc) ->
{Pos, iolist_to_binary(lists:reverse(Acc)), lists:reverse(lists:flatten(VarsAcc))};
instructions(nil, Funcs, Pos, Acc, VarsAcc) ->
{Pos, iolist_to_binary(lists:reverse(Acc)), lists:reverse(lists:flatten(VarsAcc)), Funcs};
instructions({Instr, Next}, Funcs, Pos, Acc, VarsAcc) ->
{Inc, Bin, Vars} = instruction(Instr, Funcs, Pos),
instructions(Next, Funcs, Pos + Inc, [Bin|Acc], [Vars|VarsAcc]).
{Inc, Bin, Vars, Funcs2} = instruction(Instr, Funcs, Pos),
instructions(Next, Funcs2, Pos + Inc, [Bin|Acc], [Vars|VarsAcc]).
instruction({call, Name}, Funcs, Pos) ->
N = find_func(Name, Funcs),
{2, << 96:32/little, 16#ffffffff:32 >>, [{N, Pos + 1}]};
%% High level constructs.
instruction({'case', Tests}, Funcs, Pos) ->
{Pos2, Bin, Vars} = case_tests(Tests, Funcs, Pos),
{Pos2 - Pos, Bin, Vars};
instruction({push, N}, _Funcs, _Pos) when is_integer(N) ->
{2, << 2:32/little, N:32/little >>, []};
instruction({push, Str}, _Funcs, _Pos) when is_list(Str) ->
L = length(Str),
L2 = L + 4 - L rem 4,
L3 = L2 div 4,
Padding = 8 * (L2 - L),
{Pos2, Bin, Vars, Funcs2} = case_tests(Tests, Funcs, Pos),
{Pos2 - Pos, Bin, Vars, Funcs2};
%% Functions and syscalls.
instruction({function, {Name, Type}}, Funcs, Pos) ->
{N2, Funcs2} = case find_func(Name, Funcs) of
{{error, undefined}, N} -> {N, [Name|Funcs]};
{ok, N} -> {N, Funcs}
end,
SyncBin = case Type of sync -> << 16#56:32/little >>; _ -> << >> end,
{2 + byte_size(SyncBin) div 4, << 16#60:32/little, 16#ffffffff:32, SyncBin/binary >>, [{N2, Pos + 1}], Funcs2};
instruction({syscall, {N, async}}, Funcs, _Pos) ->
{2, << 16#61:32/little, N:32/little >>, [], Funcs};
instruction({syscall, {N, sync}}, Funcs, _Pos) ->
{3, << 16#61:32/little, N:32/little, 16#56:32/little >>, [], Funcs};
%% Low level instructions.
instruction('abs', Funcs, _Pos) ->
{1, << 16#11:32/little >>, [], Funcs};
instruction(add, Funcs, _Pos) ->
{1, << 16#04:32/little >>, [], Funcs};
instruction('band', Funcs, _Pos) ->
{1, << 16#0b:32/little >>, [], Funcs};
instruction('bor', Funcs, _Pos) ->
{1, << 16#0c:32/little >>, [], Funcs};
instruction('bxor', Funcs, _Pos) ->
{1, << 16#0d:32/little >>, [], Funcs};
instruction(dec, Funcs, _Pos) ->
{1, << 16#0f:32/little >>, [], Funcs};
instruction('div', Funcs, _Pos) ->
{1, << 16#07:32/little >>, [], Funcs};
instruction(inc, Funcs, _Pos) ->
{1, << 16#0e:32/little >>, [], Funcs};
instruction(is_eq, Funcs, _Pos) ->
{1, << 16#12:32/little >>, [], Funcs};
instruction(is_gt, Funcs, _Pos) ->
{1, << 16#15:32/little >>, [], Funcs};
instruction(is_gteq, Funcs, _Pos) ->
{1, << 16#14:32/little >>, [], Funcs};
instruction(is_lt, Funcs, _Pos) ->
{1, << 16#17:32/little >>, [], Funcs};
instruction(is_lteq, Funcs, _Pos) ->
{1, << 16#16:32/little >>, [], Funcs};
instruction(is_neq, Funcs, _Pos) ->
{1, << 16#13:32/little >>, [], Funcs};
instruction({jmp, N}, Funcs, _Pos) ->
{2, << 16#2c:32/little, N:32/little-signed >>, [], Funcs};
instruction({jnz, N}, Funcs, _Pos) ->
{2, << 16#2e:32/little, N:32/little-signed >>, [], Funcs};
instruction({jz, N}, Funcs, _Pos) ->
{2, << 16#2d:32/little, N:32/little-signed >>, [], Funcs};
instruction(land, Funcs, _Pos) ->
{1, << 16#18:32/little >>, [], Funcs};
instruction(lor, Funcs, _Pos) ->
{1, << 16#19:32/little >>, [], Funcs};
instruction(lshift, Funcs, _Pos) ->
{1, << 16#09:32/little >>, [], Funcs};
instruction(mod, Funcs, _Pos) ->
{1, << 16#08:32/little >>, [], Funcs};
instruction(mul, Funcs, _Pos) ->
{1, << 16#06:32/little >>, [], Funcs};
instruction(neg, Funcs, _Pos) ->
{1, << 16#10:32/little >>, [], Funcs};
instruction(nop, Funcs, _Pos) ->
{1, << 16#01:32/little >>, [], Funcs};
instruction({num_get, {Name, _Type}}, Funcs, Pos) ->
{ok, N} = find_func(Name, Funcs),
{2, << 16#3c:32/little, 16#ffffffff:32 >>, [{N, Pos + 1}], Funcs};
instruction({num_set, {Name, _Type}}, Funcs, Pos) ->
{ok, N} = find_func(Name, Funcs),
{2, << 16#3d:32/little, 16#ffffffff:32 >>, [{N, Pos + 1}], Funcs};
instruction({push, I}, Funcs, _Pos) when is_integer(I) ->
{2, << 16#02:32/little, I:32/little-signed >>, [], Funcs};
instruction({push, F}, Funcs, _Pos) when is_float(F) ->
{2, << 16#03:32/little, F:32/little-signed-float >>, [], Funcs};
instruction({push, Str}, Funcs, _Pos) when is_list(Str) ->
StrBin = list_to_binary(Str),
{3 + L3, << 70:32/little, L3:32/little, StrBin/binary, 0:Padding >>, []};
instruction({subcall, Name}, Funcs, Pos) ->
N = find_func(Name, Funcs),
{2, << 76:32/little, 16#ffffffff:32 >>, [{N, Pos + 1}]};
instruction({syscall, N}, _Funcs, _Pos) ->
{2, << 97:32/little, N:32/little >>, []}.
L = length(Str),
Padding = 8 * (4 - L rem 4),
StrBin2 = << StrBin/binary, 0:Padding >>,
Size = byte_size(StrBin2) div 4,
{2 + Size, << 16#46:32/little, Size:32/little, StrBin2/binary >>, [], Funcs};
instruction(restore, Funcs, _Pos) ->
{1, << 16#1b:32/little >>, [], Funcs};
instruction(return, Funcs, _Pos) ->
{1, << 16#00:32/little >>, [], Funcs};
instruction(rshift, Funcs, _Pos) ->
{1, << 16#0a:32/little >>, [], Funcs};
instruction(save, Funcs, _Pos) ->
{1, << 16#1a:32/little >>, [], Funcs};
instruction(savep, Funcs, _Pos) ->
{1, << 16#1d:32/little >>, [], Funcs};
instruction({str_get, {Name, _Type}}, Funcs, Pos) ->
{ok, N} = find_func(Name, Funcs),
{2, << 16#49:32/little, 16#ffffffff:32 >>, [{N, Pos + 1}], Funcs};
instruction({str_set, {Name, _Type}}, Funcs, Pos) ->
{ok, N} = find_func(Name, Funcs),
{2, << 16#4a:32/little, 16#ffffffff:32 >>, [{N, Pos + 1}], Funcs};
instruction(sub, Funcs, _Pos) ->
{1, << 16#05:32/little >>, [], Funcs};
%% Debug instruction. Do nothing by default. Change it to whatever needs testing.
instruction(debug, Funcs, _Pos) ->
Bin = << 16#01:32/little >>,
{byte_size(Bin) div 4, Bin, [], Funcs}.
case_tests(Tests, Funcs, Pos) ->
case_tests(Tests, Funcs, Pos, [], []).
case_tests(nil, _Funcs, Pos, Acc, VarsAcc) ->
{Pos, case_tests_end(lists:reverse(Acc)), VarsAcc};
case_tests(nil, Funcs, Pos, Acc, VarsAcc) ->
{Pos, case_tests_end(lists:reverse(Acc)), VarsAcc, Funcs};
case_tests({{case_default, Instrs}, Next}, Funcs, Pos, Acc, VarsAcc) ->
{Pos2, InstrsBin, VarsList} = instructions(Instrs, Funcs, Pos),
case_tests(Next, Funcs, Pos2, [InstrsBin|Acc], [VarsList|VarsAcc]);
{Pos2, InstrsBin, VarsList, Funcs2} = instructions(Instrs, Funcs, Pos),
case_tests(Next, Funcs2, Pos2, [InstrsBin|Acc], [VarsList|VarsAcc]);
case_tests({{case_test, N, Instrs}, Next}, Funcs, Pos, Acc, VarsAcc) ->
{Pos2, InstrsBin, VarsList} = instructions(Instrs, Funcs, Pos + 7),
{Pos2, InstrsBin, VarsList, Funcs2} = instructions(Instrs, Funcs, Pos + 7),
Jump = Pos2 - Pos - 4,
TestBin = << 2:32/little, N:32/little, 29:32/little, 18:32/little,
45:32/little, Jump:32/little, 27:32/little, InstrsBin/binary >>,
case_tests(Next, Funcs, Pos2, [TestBin|Acc], [VarsList|VarsAcc]).
TestBin = << 16#02:32/little, N:32/little-signed, 16#1d:32/little, 16#12:32/little,
16#2d:32/little, Jump:32/little, 16#1b:32/little, InstrsBin/binary >>,
case_tests(Next, Funcs2, Pos2 + 2, [TestBin|Acc], [VarsList|VarsAcc]).
case_tests_end(Tests) ->
case_tests_end(Tests, []).
@ -105,7 +200,7 @@ case_tests_end([], Acc) ->
case_tests_end([TestBin|Tail], Acc) ->
TailBin = iolist_to_binary(Tail),
Jump = byte_size(TailBin) div 4 + 2 * length(Tail),
case_tests_end(Tail, [<< TestBin/binary, 44:32/little, Jump:32/little >>|Acc]).
case_tests_end(Tail, [<< TestBin/binary, 16#2c:32/little, Jump:32/little >>|Acc]).
funcs(Funcs) ->
funcs(Funcs, []).
@ -118,7 +213,9 @@ funcs([Name|Tail], Acc) ->
find_func(Name, Funcs) ->
find_func(Name, lists:reverse(Funcs), 0).
find_func(_Name, [], N) ->
{{error, undefined}, N};
find_func(Name, [Func|_Tail], N) when Name =:= Func ->
N;
{ok, N};
find_func(Name, [_Func|Tail], N) ->
find_func(Name, Tail, N + 1).

View File

@ -20,47 +20,463 @@
Definitions.
D = [0-9]
L = [a-z]
L = [a-zA-Z]
N = ({L}|{D}|_)
WS = ([\000-\s]|%.*)
Rules.
{D}+ : {token, {integer, TokenLine, list_to_integer(TokenChars)}}.
{N}+ : {token, case reserved_word(TokenChars) of
false -> case syscall(TokenChars) of
false -> {name, TokenLine, TokenChars};
Syscall -> {syscall, TokenLine, Syscall}
end;
KeyWord -> {KeyWord, TokenLine}
end}.
"(\\\^.|\\.|[^"])*" : %% Strip quotes.
S = lists:sublist(TokenChars, 2, TokenLen - 2),
{token, {string, TokenLine, string_gen(S)}}.
-> : {token, {'->', TokenLine}}.
[}{,;] : {token, {list_to_atom(TokenChars), TokenLine}}.
\.{WS} : {end_token, {dot, TokenLine}}.
{WS}+ : skip_token.
-*{D}+ : {token, {integer, TokenLine, list_to_integer(TokenChars)}}.
-*{D}+\.{D}+ : {token, {float, TokenLine, list_to_float(TokenChars)}}.
{N}+\.*{N}+ : {token, case reserved_word(TokenChars) of
false -> case syscall(TokenChars) of
false -> {function, TokenLine, function(TokenChars)};
Syscall -> {syscall, TokenLine, Syscall}
end;
KeyWord -> {KeyWord, TokenLine}
end}.
"(\\\^.|\\.|[^"])*" : %% Strip quotes.
S = lists:sublist(TokenChars, 2, TokenLen - 2),
{token, {string, TokenLine, string_gen(S)}}.
-> : {token, {'->', TokenLine}}.
[}{,;] : {token, {list_to_atom(TokenChars), TokenLine}}.
\.{WS} : {end_token, {dot, TokenLine}}.
{WS}+ : skip_token.
Erlang code.
reserved_word("call") -> call;
%% Reserved words.
reserved_word("debug") -> debug;
%% Definitions.
reserved_word("event") -> event_def;
reserved_word("function") -> function_def;
reserved_word("num_var") -> num_var;
reserved_word("str_var") -> str_var;
%% Low level opcodes.
reserved_word("abs") -> abs;
reserved_word("add") -> add;
reserved_word("band") -> 'band';
reserved_word("bor") -> 'bor';
reserved_word("bxor") -> 'bxor';
reserved_word("dec") -> dec;
reserved_word("div") -> 'div';
reserved_word("inc") -> inc;
reserved_word("is_eq") -> is_eq;
reserved_word("is_gt") -> is_gt;
reserved_word("is_gteq") -> is_gteq;
reserved_word("is_lt") -> is_lt;
reserved_word("is_lteq") -> is_lteq;
reserved_word("is_neq") -> is_neq;
reserved_word("jmp") -> jmp;
reserved_word("jnz") -> jnz;
reserved_word("jz") -> jz;
reserved_word("land") -> land;
reserved_word("lor") -> lor;
reserved_word("lshift") -> lshift;
reserved_word("mod") -> mod;
reserved_word("mul") -> mul;
reserved_word("neg") -> neg;
reserved_word("nop") -> nop;
reserved_word("num_get") -> num_get;
reserved_word("num_set") -> num_set;
reserved_word("push") -> push;
reserved_word("restore") -> restore;
reserved_word("return") -> return;
reserved_word("rshift") -> rshift;
reserved_word("save") -> save;
reserved_word("savep") -> savep;
reserved_word("str_get") -> str_get;
reserved_word("str_set") -> str_set;
reserved_word("sub") -> sub;
%% Case statement.
reserved_word("case") -> 'case';
reserved_word("default") -> default;
reserved_word("end") -> 'end';
reserved_word("event") -> event;
reserved_word("external") -> external;
reserved_word("function") -> function;
reserved_word("push") -> push;
reserved_word("subcall") -> subcall;
%% Otherwise isn't a reserved word.
reserved_word(_) -> false.
syscall("disable_gamepad") -> 158;
syscall("enable_gamepad") -> 159;
syscall("play_music") -> 253;
syscall("set_value_flag") -> 285;
syscall(_) -> false.
%% Syscalls.
syscall("mes.fukidasi_pc") -> {100, sync};
syscall("mes.fukidasi_apc") -> {101, sync};
syscall("mes.fukidasi_npc") -> {102, sync};
syscall("mes.fukidasi_pc_type") -> {103, sync};
syscall("mes.fukidasi_apc_type") -> {104, sync};
syscall("mes.fukidasi_npc_type") -> {105, sync};
syscall("mes.fukidasi_custom") -> {106, sync};
syscall("mes.erase_fukidasi") -> {107, async};
syscall("mes.chat_pc") -> {108, async};
syscall("mes.cut_in_chat") -> {109, async};
syscall("mes.cut_in_chat_custom") -> {110, async};
syscall("mes.system_win") -> {111, sync};
syscall("mes.custom_win") -> {112, sync};
syscall("mes.scroll_win") -> {113, sync};
syscall("mes.win_move") -> {114, async};
syscall("mes.erase_system_win") -> {115, async};
syscall("mes.select_win") -> {116, sync};
syscall("mes.select_win_set") -> {117, sync};
syscall("mes.select_win_single") -> {118, sync};
syscall("mes.select_win_custom") -> {119, sync};
syscall("mes.select_win_fukidasi") -> {120, sync};
syscall("mes.select_win_b") -> {121, sync};
syscall("mes.select_win_set_b") -> {122, sync};
syscall("mes.select_win_single_b") -> {123, sync};
syscall("mes.select_win_custom_b") -> {124, sync};
syscall("mes.select_win_fukidasi_b") -> {125, sync};
syscall("mes.erase_select_win") -> {126, sync};
syscall("mes.message_end") -> {127, async};
syscall("mes.set_name_npc") -> {128, async};
syscall("mes.set_color_npc") -> {129, async};
syscall("mes.line_window") -> {130, async};
syscall("adv.cut_in") -> {131, async};
syscall("adv.cut_in_custom") -> {132, async};
syscall("adv.window_disable") -> {133, async};
syscall("adv.window_enable") -> {134, async};
syscall("adv.fukidasi_disable") -> {135, async};
syscall("adv.fukidasi_enable") -> {136, async};
syscall("adv.player_disable") -> {137, async};
syscall("adv.player_enable") -> {138, async};
syscall("adv.chat_on") -> {139, async};
syscall("adv.chat_off") -> {140, async};
syscall("adv.mainmenu_disable") -> {141, async};
syscall("adv.mainmenu_enable") -> {142, async};
syscall("unit_flag.on") -> {143, async};
syscall("unit_flag.off") -> {144, async};
syscall("unit_flag.reverse") -> {145, async};
syscall("unit_flag.delay_on") -> {146, async};
syscall("unit_flag.delay_off") -> {147, async};
syscall("unit_flag.delay_reverse") -> {148, async};
syscall("unit_flag.chk") -> {149, async};
syscall("player.get_my_id") -> {150, async};
syscall("player.set_pos") -> {151, async};
syscall("player.change_unit") -> {152, async};
syscall("player.turn") -> {153, async};
syscall("player.walk") -> {154, async};
syscall("player.run") -> {155, async};
syscall("player.pad_off") -> {158, async};
syscall("player.pad_on") -> {159, async};
syscall("player.get_pos") -> {160, async};
syscall("player.get_ang") -> {161, async};
syscall("player.turn_coord") -> {162, async};
syscall("player.turn_member") -> {163, async};
syscall("plymotion.item_take_off") -> {173, async};
syscall("plymotion.set_pack") -> {174, sync};
syscall("plymotion.release_pack") -> {176, async};
syscall("plymotion.set_loop") -> {177, async};
syscall("plymotion.play_one_shot") -> {178, sync};
syscall("plymotion.cancel_one_shot") -> {179, async};
syscall("plymotion.restart_one_shot") -> {180, async};
syscall("apc.create") -> {183, sync};
syscall("apc.delete") -> {184, async};
syscall("apc.delete_inx") -> {185, async};
syscall("apc.team_into") -> {186, async};
syscall("apc.team_remove") -> {187, async};
syscall("apc.set_pos") -> {188, async};
syscall("apc.turn") -> {189, async};
syscall("apc.walk") -> {190, async};
syscall("apc.run") -> {191, async};
syscall("apc.think_off") -> {194, async};
syscall("apc.think_on") -> {195, async};
syscall("apc.get_pos") -> {196, async};
syscall("apc.get_ang") -> {197, async};
syscall("apc.reserve") -> {205, async};
syscall("apc.reserve_cancel") -> {206, async};
syscall("apc.is_reserve") -> {207, async};
syscall("apc.create_lv") -> {208, sync};
syscall("apc.reserve_lv") -> {209, async};
syscall("apc.target_guard") -> {210, async};
syscall("apc.target_guard_pid") -> {211, async};
syscall("apc.target_guard_aid") -> {212, async};
syscall("apc.cancel_target_guard") -> {213, async};
syscall("apc.set_move_out_party") -> {214, async};
syscall("apc.apc_set_ban") -> {215, async};
syscall("apc.get_aid_from_pid") -> {216, async};
syscall("apc.is_apc2") -> {217, async};
syscall("apc.is_alive") -> {218, async};
syscall("camera.set") -> {219, async};
syscall("camera.move") -> {220, async};
syscall("camera.release") -> {221, async};
syscall("camera.get_pos") -> {222, async};
syscall("camera.cam_rot") -> {223, async};
syscall("camera.target_rot") -> {224, async};
syscall("camera.dist_move") -> {225, async};
syscall("camera.get_cam_angle") -> {226, async};
syscall("camera.get_target_angle") -> {227, async};
syscall("camera.get_dist") -> {228, async};
syscall("camera.set_quake") -> {229, async};
syscall("camera.stop_quake") -> {230, async};
syscall("direction.fade_in") -> {232, async};
syscall("direction.fade_out") -> {233, async};
syscall("direction.fade_out_rgba") -> {234, async};
syscall("direction.cinema_on") -> {235, async};
syscall("direction.cinema_off") -> {236, async};
syscall("direction.vib") -> {237, async};
syscall("wait.abort_cancel") -> {238, async};
syscall("temp.exit_game") -> {239, async};
syscall("movie.play_prm") -> {240, sync};
syscall("movie.play_rtm") -> {242, sync};
syscall("movie.play_event") -> {245, sync};
syscall("movie.play_sub_title") -> {246, sync};
syscall("movie.telop") -> {247, sync};
syscall("sound.play_se") -> {251, async};
syscall("sound.play_bgm") -> {253, async}; %% Unofficial name.
syscall("sound.stop_bgm") -> {256, async};
syscall("render.scene_off") -> {257, async};
syscall("render.scene_on") -> {258, async};
syscall("render.npc_all_off") -> {259, async};
syscall("render.npc_all_on") -> {260, async};
syscall("render.npc_off") -> {261, async};
syscall("render.npc_on") -> {262, async};
syscall("render.player_off") -> {263, async};
syscall("render.player_on") -> {264, async};
syscall("render.enemy_off") -> {265, async};
syscall("render.enemy_on") -> {266, async};
syscall("render.obj_off") -> {267, async};
syscall("render.obj_on") -> {268, async};
syscall("seq.is_online") -> {272, async};
syscall("seq.save_qst") -> {273, sync};
syscall("seq.get_item") -> {280, sync};
syscall("work.accountwork_get") -> {282, sync};
syscall("work.accountwork_set") -> {283, sync};
syscall("work.chrwork_get") -> {284, sync};
syscall("work.chrwork_set") -> {285, sync};
syscall("work.chrflag_get") -> {286, sync};
syscall("work.chrflag_set") -> {287, sync};
syscall("work.partyflag_on") -> {288, sync};
syscall("work.partyflag_off") -> {289, sync};
syscall("work.qstwork_get") -> {290, async};
syscall("work.qstwork_get_member") -> {291, async};
syscall("work.qstwork_set") -> {292, async};
syscall("work.partyflag_get") -> {297, async};
syscall("work.partywork_get") -> {298, async};
syscall("work.partywork_set") -> {299, async};
syscall("work.zone_cndflag_get") -> {300, async};
syscall("work.zone_cndflag_on") -> {301, async};
syscall("work.zone_cndflag_off") -> {302, async};
syscall("work.zone_sendwork_get") -> {303, async};
syscall("work.zone_sendwork_set") -> {304, async};
syscall("work.party_rand_get") -> {305, sync};
syscall("party.get_member") -> {306, async};
syscall("party.get_leader") -> {307, async};
syscall("party.chk_exist") -> {308, async};
syscall("party.sync_wait") -> {309, sync};
syscall("party.join_on") -> {310, async};
syscall("party.join_off") -> {311, async};
syscall("party.get_enemy_kill") -> {312, async};
syscall("ptcl.create") -> {315, async};
syscall("ptcl.move") -> {316, async};
syscall("ptcl.delete") -> {317, async};
syscall("col.create") -> {318, async};
syscall("col.create_lock_on") -> {319, async};
syscall("col.create_attack") -> {320, async};
syscall("col.move") -> {321, async};
syscall("col.scale") -> {322, async};
syscall("col.delete") -> {323, async};
syscall("npc.talk_on") -> {324, async};
syscall("npc.talk_off") -> {325, async};
syscall("npc.think_on") -> {326, async};
syscall("npc.think_off") -> {327, async};
syscall("npc.set_pos") -> {328, async};
syscall("npc.turn") -> {329, async};
syscall("npc.gaze") -> {330, async};
syscall("npc.walk") -> {331, async};
syscall("npc.run") -> {332, async};
syscall("npc.walk_path") -> {335, async};
syscall("npc.run_path") -> {336, async};
syscall("npc.get_pos") -> {338, async};
syscall("npc.get_ang") -> {339, async};
syscall("npc.cng_motion") -> {340, async};
syscall("npc.cancel_motion") -> {341, async};
syscall("npc.get_motion") -> {342, async};
syscall("npc.coli_end") -> {343, async};
syscall("obj.coli_end") -> {347, async}; %% Unofficial name.
syscall("status.get_posflag") -> {354, async};
syscall("lobby.start") -> {356, sync};
syscall("lobby.end") -> {357, async};
syscall("lobby.select_planet") -> {358, sync};
syscall("camera.def_cng") -> {359, async};
syscall("camera.def_remove") -> {360, async};
syscall("camera.def_move_back") -> {361, async};
syscall("camera.def_set_back") -> {362, async};
syscall("camera.def_set_quake") -> {364, async};
syscall("camera.def_stop_qake") -> {365, async};
syscall("calc.get_rot") -> {373, async};
syscall("sjis.fukidasi_pc") -> {389, sync};
syscall("sjis.fukidasi_apc") -> {390, sync};
syscall("sjis.fukidasi_npc") -> {391, sync};
syscall("sjis.fukidasi_pc_type") -> {392, sync};
syscall("sjis.fukidasi_apc_type") -> {393, sync};
syscall("sjis.fukidasi_npc_type") -> {394, sync};
syscall("sjis.fukidasi_custom") -> {395, sync};
syscall("sjis.chat_pc") -> {396, async};
syscall("sjis.cut_in_chat") -> {397, async};
syscall("sjis.cut_in_chat_custom") -> {398, async};
syscall("sjis.system_win") -> {399, sync};
syscall("sjis.custom_win") -> {400, sync};
syscall("sjis.scroll_win") -> {401, sync};
syscall("sjis.select_win") -> {402, sync};
syscall("sjis.select_win_set") -> {403, sync};
syscall("sjis.select_win_single") -> {404, sync};
syscall("sjis.select_win_custom") -> {405, sync};
syscall("sjis.select_win_fukidasi") -> {406, sync};
syscall("sjis.select_win_b") -> {407, sync};
syscall("sjis.select_win_set_b") -> {408, sync};
syscall("sjis.select_win_single_b") -> {409, sync};
syscall("sjis.select_win_custom_b") -> {410, sync};
syscall("sjis.select_win_fukidasi_b") -> {411, sync};
syscall("sjis.line_window") -> {412, async};
syscall("temp.line") -> {413, async};
syscall("temp.sline") -> {414, async};
syscall(_) -> false.
%% Functions.
function("adv.cut_in_load") -> {"q.adv.cut_in_load", async};
function("adv.cut_in_noise") -> {"q.adv.cut_in_noise", async};
function("adv.cut_in_release") -> {"q.adv.cut_in_release", async};
function("adv.cut_in_stop") -> {"q.adv.cut_in_stop", async};
%% @todo apc.apc_sp_exec
%% @todo q.apc.create_ex
function("apc.get_reserve_aid_all") -> {"apc.get_reserve_aid_all", async};
function("apc.get_reserve_count") -> {"apc.get_reserve_count", async};
function("apc.guildcard_disable") -> {"apc.guildcard_disable", async};
function("apc.guildcard_enable") -> {"apc.guildcard_enable", async};
function("apc.impossible_join_pt") -> {"apc.impossible_join_pt", async};
function("apc.is_set_ban") -> {"apc.is_set_ban", async};
%% @todo apc.move
%% @todo apc.move_xz
function("apc.possible_join_pt") -> {"apc.possible_join_pt", async};
%% @todo apc.set_goal_out_party
function("apc.set_sp_ban") -> {"apc.set_sp_ban", async};
function("apc.set_talk_ban") -> {"apc.set_talk_ban", async};
function("counter.create_dc_map") -> {"counter.create_dc_map", async};
function("counter.delete_dc_map") -> {"counter.delete_dc_map", async};
function("counter.set_arrow_pos") -> {"counter.set_arrow_pos", async};
function("counter.set_lookon_pos") -> {"counter.set_lookon_pos", async};
function("direction.fade_out_nowloading") -> {"direction.fade_out_nowloading", async};
function("font.set_party_member_id") -> {"font.set_party_member_id", async};
function("item.exchange") -> {"q.seq.exchange_item", sync};
function("item.get_num") -> {"q.seq.get_item_num", sync};
function("item.get_slot_num_req") -> {"q.item.get_slot_num_req", sync};
function("item.get_slot_num_ret") -> {"q.item.get_slot_num_ret", async};
%% @todo item.set_ability
function("mes.mes_broadcast_clear") -> {"mes.mes_broadcast_clear", async};
%% @todo mes.mes_broadcast_clear_all
function("mes.mes_broadcast_set") -> {"mes.mes_broadcast_set", async};
function("mes.line_window_time") -> {"q.mes.line_window_line_time", async};
function("mes.select_win_number") -> {"q.mes.select_win_number", sync};
function("movie.text_prm_delay") -> {"movie.text_prm_delay", async};
function("myroom.check_data_load") -> {"myroom.check_data_load", async};
function("myroom.disable_obj_ex") -> {"myroom.disable_obj_ex", async};
function("myroom.get_move_planet") -> {"myroom.get_move_planet", async};
function("myroom.get_probo_ang") -> {"myroom.get_probo_ang", async};
function("myroom.get_probo_pos") -> {"myroom.get_probo_pos", async};
function("myroom.get_probo_rank") -> {"myroom.get_probo_rank", async};
function("myroom.news_enable") -> {"myroom.news_enable", async};
%% @todo myroom.get_probo_type
function("npc.gaze_cancel") -> {"npc.gaze_cancel", async};
%% @todo npc.get_head_y
function("npc.is_load_comp") -> {"npc.is_load_comp", async};
%% @todo q.npc.run_fast
%% @todo npc.run_xz_fast
%% @todo q.npc.walk_fast
%% @todo npc.walk_xz_fast
%% @todo obj.chair_disable
%% @todo obj.chair_enable
function("obj.get_eventflag") -> {"obj.get_eventflag", async};
function("obj.set_caption") -> {"obj.set_caption", async};
function("obj.vehicle_resetpos") -> {"obj.vehicle_resetpos", async};
function("player.display") -> {"player.display", async};
function("player.disp_off_except_party") -> {"player.disp_off_except_party", async};
function("player.disp_on_except_party") -> {"player.disp_on_except_party", async};
function("player.face_set") -> {"player.face_set", async};
%% @todo player.gaze_body
%% @todo player.get_action
function("player.get_level") -> {"player.get_level", async};
function("player.get_my_pmid") -> {"q.player.get_my_pmid", async};
function("player.get_occupation") -> {"player.get_occupation", async};
function("player.get_off_vehicle") -> {"player.get_off_vehicle", async};
%% @todo player.get_on_vehicle
function("player.get_race") -> {"player.get_race", async};
function("player.get_sex") -> {"player.get_sex", async};
function("player.hide") -> {"player.hide", async};
function("player.is_dead") -> {"player.is_dead", async};
%% @todo player.is_equipping_item
function("player.is_in_sp") -> {"player.is_in_sp", async};
function("player.is_on_vehicle") -> {"player.is_on_vehicle", async};
%% @todo player.move
%% @todo player.move_xz
%% @todo player.set_vehicle_breakpos
function("player.sp_cancel") -> {"player.sp_cancel", async};
%% @todo player.turn_round
%% @todo player.turn_round_coord_xz
function("plymotion.can_i_set_event_pack") -> {"plymotion.can_i_set_event_pack", async};
%% @todo plymotion.get_pack
function("plymotion.is_ready") -> {"plymotion.is_ready", async};
function("plymotion.item_re_equip") -> {"plymotion.item_re_equip", async};
%% @todo radar.display
%% @todo radar.fullclose
function("radar.fullopen") -> {"radar.fullopen", async};
%% @todo radar.hide
function("seq.endroll_play") -> {"q.seq.endroll_play", sync};
%% @todo seq.get_death_count
%% @todo seq.get_death_count_apc
function("seq.get_destroy_enemy_count") -> {"seq.get_destroy_enemy_count", async};
function("seq.get_elapsed_time") -> {"seq.get_elapsed_time", async};
function("seq.get_judgement") -> {"seq.get_judgement", async};
function("seq.get_mission_step") -> {"seq.get_mission_step", async};
function("seq.get_rank") -> {"seq.get_rank", async};
%% @todo seq.get_remaining_time
%% @todo seq.get_setdata_inx
%% @todo seq.goto_title
function("seq.has_finished_result") -> {"seq.has_finished_result", async};
function("seq.open_ex_mode") -> {"seq.open_ex_mode", async};
function("seq.preview_network") -> {"q.seq.preview_network", sync};
function("seq.preview_play") -> {"q.seq.preview_play", sync};
function("seq.result") -> {"q.seq.result", async};
function("seq.save_menu") -> {"q.seq.save_menu", sync};
%% @todo seq.set_chapter_no
function("seq.set_ex_chapter_no") -> {"seq.set_ex_chapter_no", async};
%% @todo seq.set_story_end_flag
function("seq.staffroll_play") -> {"q.seq.staffroll_play", sync};
%% @todo q.seq.unify_counter
function("shop.open") -> {"shop.open", async};
%% @todo shop.req_load_data
function("sjis.line_window_time") -> {"q.sjis.line_window_time", async};
function("sound.check_jingle") -> {"sound.check_jingle", async};
%% @todo sound.get_player_pack
function("sound.load_enemy_pack") -> {"sound.load_enemy_pack", async};
%% @todo sound.load_enemy_port_pack
function("sound.load_event_pack") -> {"sound.load_event_pack", async};
function("sound.load_player_pack") -> {"sound.load_player_pack", async};
%% @todo sound.pause_adx_voice
function("sound.pause_bgm") -> {"sound.pause_bgm", async};
function("sound.play_jingle") -> {"sound.play_jingle", async};
function("sound.play_se3d_loop_stop") -> {"sound.play_se3d_loop_stop", async};
function("sound.play_se3d_loop_vol") -> {"sound.play_se3d_loop_vol", async};
function("sound.play_player") -> {"q.sound.play_player", sync};
function("sound.play_se3d") -> {"q.sound.play_se3d", sync};
%% @todo sound.play_se3d_loop
function("sound.play_se3d_vol") -> {"q.sound.play_se3d_vol", sync};
function("sound.play_technique") -> {"sound.play_technique", async};
function("sound.play_vehicle") -> {"sound.play_vehicle", async};
function("sound.stop_adx_voice") -> {"sound.stop_adx_voice", async};
function("system.frame_adjust") -> {"system.frame_adjust", async};
%% @todo system.frame_default
function("system.frame_get") -> {"system.frame_get", async};
%% @todo system.frame_set
function("system.get_episode") -> {"system.get_episode", async};
%% @todo system.get_language
function("system.get_platform") -> {"system.get_platform", async};
function("system.get_resolution") -> {"system.get_resolution", async};
function("work.get_stamp_bonus") -> {"q.work.get_stamp_bonus", sync};
function("work.get_stamp_num") -> {"q.work.get_stamp_num", sync};
function("work.get_stamp_quest") -> {"q.work.get_stamp_quest", sync};
%% @todo q.work.on_accountwork_get
function("work.partyworknum_get") -> {"q.work.partyworknum_get", async};
function("work.partyworknum_set") -> {"q.work.partyworknum_set", async};
%% @todo q.work.stamp_command
function(Name) -> {Name, local}.
%% Strings.
string_gen([$\\|Cs]) ->
string_escape(Cs);
string_gen([C|Cs]) ->

View File

@ -18,26 +18,67 @@
%% along with EGS. If not, see <http://www.gnu.org/licenses/>.
Nonterminals declarations declaration instructions instruction case_tests case_test case_default.
Terminals integer name string call case default end event external function push subcall syscall '->' ',' ';' dot.
Terminals
integer float string function syscall debug event_def function_def num_var str_var
abs add band bor bxor dec div inc is_eq is_gt is_gteq is_lt is_lteq is_neq
jmp jnz jz land lor lshift mod mul neg nop num_get num_set push restore return
rshift save savep str_get str_set sub case default end '->' ',' ';' dot.
Rootsymbol declarations.
declarations -> declaration declarations : {'$1', '$2'}.
declarations -> '$empty' : nil.
declaration -> event name '->' instructions dot : {event, unwrap('$2'), '$4'}.
declaration -> external string dot : {external, unwrap('$2')}.
declaration -> function name '->' instructions dot : {function, unwrap('$2'), '$4'}.
declaration -> event_def function '->' instructions dot : {event_def, unwrap('$2'), '$4'}.
declaration -> function_def function '->' instructions dot : {function_def, unwrap('$2'), '$4'}.
declaration -> num_var function dot : {num_var, unwrap('$2')}.
declaration -> str_var function integer dot : {str_var, unwrap('$2'), unwrap('$3')}.
instructions -> instruction ',' instructions : {'$1', '$3'}.
instructions -> instruction : {'$1', nil}.
instruction -> call string : {call, unwrap('$2')}.
instruction -> 'case' case_tests 'end' : {'case', '$2'}.
instruction -> push integer : {push, unwrap('$2')}.
instruction -> push string : {push, unwrap('$2')}.
instruction -> subcall string : {subcall, unwrap('$2')}.
instruction -> syscall : {syscall, unwrap('$1')}.
instruction -> abs : abs.
instruction -> add : add.
instruction -> band : 'band'.
instruction -> bor : 'bor'.
instruction -> bxor : 'bxor'.
instruction -> dec : dec.
instruction -> div : 'div'.
instruction -> inc : inc.
instruction -> is_eq : is_eq.
instruction -> is_gt : is_gt.
instruction -> is_gteq : is_gteq.
instruction -> is_lt : is_lt.
instruction -> is_lteq : is_lteq.
instruction -> is_neq : is_neq.
instruction -> jmp integer : {jmp, unwrap('$2')}.
instruction -> jnz integer : {jnz, unwrap('$2')}.
instruction -> jz integer : {jz, unwrap('$2')}.
instruction -> land : land.
instruction -> lor : lor.
instruction -> lshift : lshift.
instruction -> mod : mod.
instruction -> mul : mul.
instruction -> neg : neg.
instruction -> nop : nop.
instruction -> num_get function : {num_get, unwrap('$2')}.
instruction -> num_set function : {num_set, unwrap('$2')}.
instruction -> push integer : {push, unwrap('$2')}.
instruction -> push float : {push, unwrap('$2')}.
instruction -> push string : {push, unwrap('$2')}.
instruction -> restore : restore.
instruction -> return : return.
instruction -> rshift : rshift.
instruction -> save : save.
instruction -> savep : savep.
instruction -> str_get function : {str_get, unwrap('$2')}.
instruction -> str_set function : {str_set, unwrap('$2')}.
instruction -> sub : sub.
instruction -> debug : debug.
instruction -> function : {function, unwrap('$1')}.
instruction -> syscall : {syscall, unwrap('$1')}.
instruction -> 'case' case_tests 'end' : {'case', '$2'}.
case_tests -> case_test ';' case_tests : {'$1', '$3'}.
case_tests -> case_test ';' case_default : {'$1', {'$3', nil}}.
case_tests -> case_test : {'$1', nil}.