From b57f78611146e1aeb0d34d71f32f615b4273c164 Mon Sep 17 00:00:00 2001 From: Mikhail Butvin Date: Mon, 11 Nov 2024 09:57:56 +0300 Subject: [PATCH] Stateless (#1) * Allow passing argv to the main entry function * Export malloc * Support re-invokation of the Refal VM entry function, add example with animation --- examples/canvas/build.sh | 2 +- examples/canvas/main.c | 488 +++++++++++++++++++++++++++++++++----- examples/canvas/main.ref | 36 ++- examples/canvas/main.wasm | Bin 62344 -> 78916 bytes index.html | 92 ++++--- lib/lamelib.js | 11 +- lib/lamestd.h | 18 +- lib/refal05rts.c | 82 ++++++- lib/refal05rts.h | 4 +- 9 files changed, 613 insertions(+), 120 deletions(-) diff --git a/examples/canvas/build.sh b/examples/canvas/build.sh index 260f216..b213508 100755 --- a/examples/canvas/build.sh +++ b/examples/canvas/build.sh @@ -1,3 +1,3 @@ export R05ROOT="/home/butvinm/Dev/lame-refal" export R05PATH="$R05ROOT/lib:$R05ROOT/src:$R05ROOT/examples/canvas" -R05CCOMP="clang -DLAMELIB -target wasm32 -ffreestanding --no-standard-libraries -fno-builtin -Wl,--export-table -Wl,--no-entry -Wl,--export=main -Wl,--allow-undefined -o main.wasm" $R05ROOT/bin/refal05c main refal05rts Library Canvas +R05CCOMP="clang -DLAMELIB -target wasm32 -ffreestanding --no-standard-libraries -fno-builtin -Wl,--export-table -Wl,--no-entry -Wl,--export=main -Wl,--export=malloc -Wl,--allow-undefined -o main.wasm" $R05ROOT/bin/refal05c main refal05rts Library Canvas diff --git a/examples/canvas/main.c b/examples/canvas/main.c index 5678e09..a8186dc 100644 --- a/examples/canvas/main.c +++ b/examples/canvas/main.c @@ -2,15 +2,25 @@ #include "refal05rts.h" +R05_DECLARE_ENTRY_FUNCTION(Add) +R05_DECLARE_ENTRY_FUNCTION(Arg) +R05_DECLARE_ENTRY_FUNCTION(Mul) +R05_DECLARE_ENTRY_FUNCTION(Numb) R05_DECLARE_ENTRY_FUNCTION(FillRect) R05_DECLARE_ENTRY_FUNCTION(SetFillStyle) R05_DECLARE_ENTRY_FUNCTION(Go) +R05_DECLARE_LOCAL_FUNCTION(FFInteger) +R05_DECLARE_LOCAL_FUNCTION(CanvasWidth) +R05_DECLARE_LOCAL_FUNCTION(CanvasHeight) +R05_DECLARE_LOCAL_FUNCTION(StripWidth) +R05_DECLARE_LOCAL_FUNCTION(StripHeight) +R05_DECLARE_LOCAL_FUNCTION(Draw) R05_DEFINE_ENTRY_FUNCTION(Go, "Go") { r05_this_is_generated_function(); do { - struct r05_node *p[26] = { 0 }; + struct r05_node *p[8] = { 0 }; /* */ p[0] = arg_begin->next; p[1] = arg_end; @@ -19,101 +29,461 @@ R05_DEFINE_ENTRY_FUNCTION(Go, "Go") { r05_reset_allocator(); r05_alloc_open_call(p+2); - r05_alloc_function(&r05f_SetFillStyle); - r05_alloc_chars("rgb(228 3 3)", 12); - r05_alloc_close_call(p+3); + r05_alloc_function(&r05f_Draw); + r05_alloc_open_call(p+3); + r05_alloc_function(&r05f_FFInteger); r05_alloc_open_call(p+4); - r05_alloc_function(&r05f_FillRect); + r05_alloc_function(&r05f_Arg); r05_alloc_number(0UL); - r05_alloc_number(0UL); - r05_alloc_number(200UL); + r05_alloc_close_call(p+5); + r05_alloc_close_call(p+6); + r05_alloc_close_call(p+7); + r05_push_stack(p[7]); + r05_push_stack(p[2]); + r05_push_stack(p[6]); + r05_push_stack(p[3]); + r05_push_stack(p[5]); + r05_push_stack(p[4]); + r05_splice_from_freelist(arg_begin); + r05_splice_to_freelist(arg_begin, arg_end); + return; + } while (0); + + r05_recognition_impossible(); +} + +R05_DEFINE_LOCAL_FUNCTION(FFInteger, "FFInteger") { + r05_this_is_generated_function(); + + do { + /* e.Integer: 2 */ + /* e.Fractional: 5 */ + struct r05_node *p[10] = { 0 }; + /* e.Integer '.' e.Fractional */ + p[0] = arg_begin->next; + p[1] = arg_end; + p[2] = p[0]->next; + p[3] = p[0]; + r05_start_e_loop(); + do { + if (! r05_char_left(p+4, p[3], p[1], '.')) + continue; + r05_close_evar(p+5, p[4], p[1]); + + r05_reset_allocator(); + r05_alloc_open_call(p+7); + r05_alloc_function(&r05f_Numb); + r05_alloc_insert_pos(p+8); + r05_alloc_close_call(p+9); + r05_push_stack(p[9]); + r05_push_stack(p[7]); + r05_correct_evar(p+2); + r05_splice_evar(p[8], p+2); + r05_splice_from_freelist(arg_begin); + r05_splice_to_freelist(arg_begin, arg_end); + return; + } while (r05_open_evar_advance(p+2, p[1])); + r05_stop_e_loop(); + } while (0); + + r05_recognition_impossible(); +} + +R05_DEFINE_LOCAL_FUNCTION(CanvasWidth, "CanvasWidth") { + r05_this_is_generated_function(); + + do { + struct r05_node *p[2] = { 0 }; + /* */ + p[0] = arg_begin->next; + p[1] = arg_end; + if (! r05_empty_hole(p[0], p[1])) + continue; + + r05_reset_allocator(); + r05_alloc_number(1000UL); + r05_splice_from_freelist(arg_begin); + r05_splice_to_freelist(arg_begin, arg_end); + return; + } while (0); + + r05_recognition_impossible(); +} + +R05_DEFINE_LOCAL_FUNCTION(CanvasHeight, "CanvasHeight") { + r05_this_is_generated_function(); + + do { + struct r05_node *p[2] = { 0 }; + /* */ + p[0] = arg_begin->next; + p[1] = arg_end; + if (! r05_empty_hole(p[0], p[1])) + continue; + + r05_reset_allocator(); + r05_alloc_number(1000UL); + r05_splice_from_freelist(arg_begin); + r05_splice_to_freelist(arg_begin, arg_end); + return; + } while (0); + + r05_recognition_impossible(); +} + +R05_DEFINE_LOCAL_FUNCTION(StripWidth, "StripWidth") { + r05_this_is_generated_function(); + + do { + struct r05_node *p[2] = { 0 }; + /* */ + p[0] = arg_begin->next; + p[1] = arg_end; + if (! r05_empty_hole(p[0], p[1])) + continue; + + r05_reset_allocator(); + r05_alloc_number(100UL); + r05_splice_from_freelist(arg_begin); + r05_splice_to_freelist(arg_begin, arg_end); + return; + } while (0); + + r05_recognition_impossible(); +} + +R05_DEFINE_LOCAL_FUNCTION(StripHeight, "StripHeight") { + r05_this_is_generated_function(); + + do { + struct r05_node *p[2] = { 0 }; + /* */ + p[0] = arg_begin->next; + p[1] = arg_end; + if (! r05_empty_hole(p[0], p[1])) + continue; + + r05_reset_allocator(); r05_alloc_number(10UL); + r05_splice_from_freelist(arg_begin); + r05_splice_to_freelist(arg_begin, arg_end); + return; + } while (0); + + r05_recognition_impossible(); +} + +R05_DEFINE_LOCAL_FUNCTION(Draw, "Draw") { + r05_this_is_generated_function(); + + do { + /* e.Ts: 2 */ + struct r05_node *p[121] = { 0 }; + /* e.Ts */ + p[0] = arg_begin->next; + p[1] = arg_end; + r05_close_evar(p+2, p[0], p[1]); + + r05_reset_allocator(); + r05_alloc_open_call(p+4); + r05_alloc_function(&r05f_SetFillStyle); + r05_alloc_chars("rgb(255 255 255)", 16); r05_alloc_close_call(p+5); r05_alloc_open_call(p+6); - r05_alloc_function(&r05f_SetFillStyle); - r05_alloc_chars("rgb(255 140 0)", 14); - r05_alloc_close_call(p+7); - r05_alloc_open_call(p+8); r05_alloc_function(&r05f_FillRect); r05_alloc_number(0UL); - r05_alloc_number(10UL); - r05_alloc_number(200UL); - r05_alloc_number(10UL); - r05_alloc_close_call(p+9); - r05_alloc_open_call(p+10); - r05_alloc_function(&r05f_SetFillStyle); - r05_alloc_chars("rgb(255 237 0)", 14); + r05_alloc_number(0UL); + r05_alloc_open_call(p+7); + r05_alloc_function(&r05f_CanvasWidth); + r05_alloc_close_call(p+8); + r05_alloc_open_call(p+9); + r05_alloc_function(&r05f_CanvasHeight); + r05_alloc_close_call(p+10); r05_alloc_close_call(p+11); r05_alloc_open_call(p+12); - r05_alloc_function(&r05f_FillRect); - r05_alloc_number(0UL); - r05_alloc_number(20UL); - r05_alloc_number(200UL); - r05_alloc_number(10UL); + r05_alloc_function(&r05f_SetFillStyle); + r05_alloc_chars("rgb(228 3 3)", 12); r05_alloc_close_call(p+13); r05_alloc_open_call(p+14); + r05_alloc_function(&r05f_FillRect); + r05_alloc_open_bracket(p+15); + r05_alloc_insert_pos(p+16); + r05_alloc_close_bracket(p+17); + r05_alloc_open_call(p+18); + r05_alloc_function(&r05f_Add); + r05_alloc_open_bracket(p+19); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+20); + r05_alloc_open_call(p+21); + r05_alloc_function(&r05f_Mul); + r05_alloc_open_call(p+22); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+23); + r05_alloc_number(0UL); + r05_alloc_close_call(p+24); + r05_alloc_close_call(p+25); + r05_alloc_open_call(p+26); + r05_alloc_function(&r05f_StripWidth); + r05_alloc_close_call(p+27); + r05_alloc_open_call(p+28); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+29); + r05_alloc_close_call(p+30); + r05_alloc_open_call(p+31); + r05_alloc_function(&r05f_SetFillStyle); + r05_alloc_chars("rgb(255 140 0)", 14); + r05_alloc_close_call(p+32); + r05_alloc_open_call(p+33); + r05_alloc_function(&r05f_FillRect); + r05_alloc_open_bracket(p+34); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+35); + r05_alloc_open_call(p+36); + r05_alloc_function(&r05f_Add); + r05_alloc_open_bracket(p+37); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+38); + r05_alloc_open_call(p+39); + r05_alloc_function(&r05f_Mul); + r05_alloc_open_call(p+40); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+41); + r05_alloc_number(1UL); + r05_alloc_close_call(p+42); + r05_alloc_close_call(p+43); + r05_alloc_open_call(p+44); + r05_alloc_function(&r05f_StripWidth); + r05_alloc_close_call(p+45); + r05_alloc_open_call(p+46); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+47); + r05_alloc_close_call(p+48); + r05_alloc_open_call(p+49); + r05_alloc_function(&r05f_SetFillStyle); + r05_alloc_chars("rgb(255 237 0)", 14); + r05_alloc_close_call(p+50); + r05_alloc_open_call(p+51); + r05_alloc_function(&r05f_FillRect); + r05_alloc_open_bracket(p+52); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+53); + r05_alloc_open_call(p+54); + r05_alloc_function(&r05f_Add); + r05_alloc_open_bracket(p+55); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+56); + r05_alloc_open_call(p+57); + r05_alloc_function(&r05f_Mul); + r05_alloc_open_call(p+58); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+59); + r05_alloc_number(2UL); + r05_alloc_close_call(p+60); + r05_alloc_close_call(p+61); + r05_alloc_open_call(p+62); + r05_alloc_function(&r05f_StripWidth); + r05_alloc_close_call(p+63); + r05_alloc_open_call(p+64); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+65); + r05_alloc_close_call(p+66); + r05_alloc_open_call(p+67); r05_alloc_function(&r05f_SetFillStyle); r05_alloc_chars("rgb(0 128 38)", 13); - r05_alloc_close_call(p+15); - r05_alloc_open_call(p+16); + r05_alloc_close_call(p+68); + r05_alloc_open_call(p+69); r05_alloc_function(&r05f_FillRect); - r05_alloc_number(0UL); - r05_alloc_number(30UL); - r05_alloc_number(200UL); - r05_alloc_number(10UL); - r05_alloc_close_call(p+17); - r05_alloc_open_call(p+18); + r05_alloc_open_bracket(p+70); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+71); + r05_alloc_open_call(p+72); + r05_alloc_function(&r05f_Add); + r05_alloc_open_bracket(p+73); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+74); + r05_alloc_open_call(p+75); + r05_alloc_function(&r05f_Mul); + r05_alloc_open_call(p+76); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+77); + r05_alloc_number(3UL); + r05_alloc_close_call(p+78); + r05_alloc_close_call(p+79); + r05_alloc_open_call(p+80); + r05_alloc_function(&r05f_StripWidth); + r05_alloc_close_call(p+81); + r05_alloc_open_call(p+82); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+83); + r05_alloc_close_call(p+84); + r05_alloc_open_call(p+85); r05_alloc_function(&r05f_SetFillStyle); r05_alloc_chars("rgb(0 77 255)", 13); - r05_alloc_close_call(p+19); - r05_alloc_open_call(p+20); + r05_alloc_close_call(p+86); + r05_alloc_open_call(p+87); r05_alloc_function(&r05f_FillRect); - r05_alloc_number(0UL); - r05_alloc_number(40UL); - r05_alloc_number(200UL); - r05_alloc_number(10UL); - r05_alloc_close_call(p+21); - r05_alloc_open_call(p+22); + r05_alloc_open_bracket(p+88); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+89); + r05_alloc_open_call(p+90); + r05_alloc_function(&r05f_Add); + r05_alloc_open_bracket(p+91); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+92); + r05_alloc_open_call(p+93); + r05_alloc_function(&r05f_Mul); + r05_alloc_open_call(p+94); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+95); + r05_alloc_number(4UL); + r05_alloc_close_call(p+96); + r05_alloc_close_call(p+97); + r05_alloc_open_call(p+98); + r05_alloc_function(&r05f_StripWidth); + r05_alloc_close_call(p+99); + r05_alloc_open_call(p+100); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+101); + r05_alloc_close_call(p+102); + r05_alloc_open_call(p+103); r05_alloc_function(&r05f_SetFillStyle); r05_alloc_chars("rgb(117 7 135)", 14); - r05_alloc_close_call(p+23); - r05_alloc_open_call(p+24); + r05_alloc_close_call(p+104); + r05_alloc_open_call(p+105); r05_alloc_function(&r05f_FillRect); - r05_alloc_number(0UL); - r05_alloc_number(50UL); - r05_alloc_number(200UL); - r05_alloc_number(10UL); - r05_alloc_close_call(p+25); + r05_alloc_open_bracket(p+106); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+107); + r05_alloc_open_call(p+108); + r05_alloc_function(&r05f_Add); + r05_alloc_open_bracket(p+109); + r05_alloc_evar(p+2); + r05_alloc_close_bracket(p+110); + r05_alloc_open_call(p+111); + r05_alloc_function(&r05f_Mul); + r05_alloc_open_call(p+112); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+113); + r05_alloc_number(5UL); + r05_alloc_close_call(p+114); + r05_alloc_close_call(p+115); + r05_alloc_open_call(p+116); + r05_alloc_function(&r05f_StripWidth); + r05_alloc_close_call(p+117); + r05_alloc_open_call(p+118); + r05_alloc_function(&r05f_StripHeight); + r05_alloc_close_call(p+119); + r05_alloc_close_call(p+120); + r05_push_stack(p[120]); + r05_push_stack(p[105]); + r05_push_stack(p[119]); + r05_push_stack(p[118]); + r05_push_stack(p[117]); + r05_push_stack(p[116]); + r05_push_stack(p[115]); + r05_push_stack(p[108]); + r05_push_stack(p[114]); + r05_push_stack(p[111]); + r05_push_stack(p[113]); + r05_push_stack(p[112]); + r05_link_brackets(p[109], p[110]); + r05_link_brackets(p[106], p[107]); + r05_push_stack(p[104]); + r05_push_stack(p[103]); + r05_push_stack(p[102]); + r05_push_stack(p[87]); + r05_push_stack(p[101]); + r05_push_stack(p[100]); + r05_push_stack(p[99]); + r05_push_stack(p[98]); + r05_push_stack(p[97]); + r05_push_stack(p[90]); + r05_push_stack(p[96]); + r05_push_stack(p[93]); + r05_push_stack(p[95]); + r05_push_stack(p[94]); + r05_link_brackets(p[91], p[92]); + r05_link_brackets(p[88], p[89]); + r05_push_stack(p[86]); + r05_push_stack(p[85]); + r05_push_stack(p[84]); + r05_push_stack(p[69]); + r05_push_stack(p[83]); + r05_push_stack(p[82]); + r05_push_stack(p[81]); + r05_push_stack(p[80]); + r05_push_stack(p[79]); + r05_push_stack(p[72]); + r05_push_stack(p[78]); + r05_push_stack(p[75]); + r05_push_stack(p[77]); + r05_push_stack(p[76]); + r05_link_brackets(p[73], p[74]); + r05_link_brackets(p[70], p[71]); + r05_push_stack(p[68]); + r05_push_stack(p[67]); + r05_push_stack(p[66]); + r05_push_stack(p[51]); + r05_push_stack(p[65]); + r05_push_stack(p[64]); + r05_push_stack(p[63]); + r05_push_stack(p[62]); + r05_push_stack(p[61]); + r05_push_stack(p[54]); + r05_push_stack(p[60]); + r05_push_stack(p[57]); + r05_push_stack(p[59]); + r05_push_stack(p[58]); + r05_link_brackets(p[55], p[56]); + r05_link_brackets(p[52], p[53]); + r05_push_stack(p[50]); + r05_push_stack(p[49]); + r05_push_stack(p[48]); + r05_push_stack(p[33]); + r05_push_stack(p[47]); + r05_push_stack(p[46]); + r05_push_stack(p[45]); + r05_push_stack(p[44]); + r05_push_stack(p[43]); + r05_push_stack(p[36]); + r05_push_stack(p[42]); + r05_push_stack(p[39]); + r05_push_stack(p[41]); + r05_push_stack(p[40]); + r05_link_brackets(p[37], p[38]); + r05_link_brackets(p[34], p[35]); + r05_push_stack(p[32]); + r05_push_stack(p[31]); + r05_push_stack(p[30]); + r05_push_stack(p[14]); + r05_push_stack(p[29]); + r05_push_stack(p[28]); + r05_push_stack(p[27]); + r05_push_stack(p[26]); r05_push_stack(p[25]); + r05_push_stack(p[18]); r05_push_stack(p[24]); + r05_push_stack(p[21]); r05_push_stack(p[23]); r05_push_stack(p[22]); - r05_push_stack(p[21]); - r05_push_stack(p[20]); - r05_push_stack(p[19]); - r05_push_stack(p[18]); - r05_push_stack(p[17]); - r05_push_stack(p[16]); - r05_push_stack(p[15]); - r05_push_stack(p[14]); + r05_link_brackets(p[19], p[20]); + r05_link_brackets(p[15], p[17]); + r05_correct_evar(p+2); r05_push_stack(p[13]); r05_push_stack(p[12]); r05_push_stack(p[11]); + r05_push_stack(p[6]); r05_push_stack(p[10]); r05_push_stack(p[9]); r05_push_stack(p[8]); r05_push_stack(p[7]); - r05_push_stack(p[6]); r05_push_stack(p[5]); r05_push_stack(p[4]); - r05_push_stack(p[3]); - r05_push_stack(p[2]); + r05_splice_evar(p[16], p+2); r05_splice_from_freelist(arg_begin); r05_splice_to_freelist(arg_begin, arg_end); return; } while (0); - - r05_recognition_impossible(); } diff --git a/examples/canvas/main.ref b/examples/canvas/main.ref index 10f0bb1..f632871 100644 --- a/examples/canvas/main.ref +++ b/examples/canvas/main.ref @@ -3,17 +3,27 @@ $EXTERN FillRect, SetFillStyle; $ENTRY Go { - = - - - - - - - - - - - - + = >>; +} + + +FFInteger { + e.Integer '.' e.Fractional = ; +} + +CanvasWidth { = 1000 } +CanvasHeight { = 1000 } +StripWidth { = 100 } +StripHeight { = 10 } + +Draw { + e.Ts = + > + + 0>> > + 1>> > + 2>> > + 3>> > + 4>> > + 5>> > } diff --git a/examples/canvas/main.wasm b/examples/canvas/main.wasm index 9389c3bb7fb74a857b594fd13158bb28da5871db..a968cf0cdfd32a29c19ef8cf0308f9b2cea9be16 100755 GIT binary patch delta 23296 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 delta 7920 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 e9w5Ij4@{%ME4=332z#Qf{UHl(j2`X}YyJ

Refal compiled to WebAssembly test

+ - + + + + + diff --git a/lib/lamelib.js b/lib/lamelib.js index ebb5016..95d80e9 100644 --- a/lib/lamelib.js +++ b/lib/lamelib.js @@ -1,5 +1,6 @@ let lameWasmInstance; +const MAX_LINE_SIZE = 4096; let output = ""; function write_impl(stream, content) { @@ -14,6 +15,10 @@ function write_impl(stream, content) { output += String.fromCharCode(memory[currentPtr]); } currentPtr++; + + if (currentPtr - content > MAX_LINE_SIZE) { + throw new Error(`At write_impl MAX_LINE_SIZE exceeded: ${MAX_LINE_SIZE}`); + } } } @@ -47,8 +52,10 @@ function getc(stream) { } function fflush(stream) { - console.log(output); - output = ""; + if (output) { + console.log(stream, output); + output = ""; + } } function exit(retcode) { diff --git a/lib/lamestd.h b/lib/lamestd.h index 761659b..026eae8 100644 --- a/lib/lamestd.h +++ b/lib/lamestd.h @@ -34,12 +34,12 @@ time_t time(time_t* t); // lamelib.js char* ctime(time_t* t); // lamelib.js // malloc.h -#define MEMORY_POOL_SIZE 1024 * 1024 * 64 +#define LAME_POOL_SIZE 1024 * 1024 * 64 void* malloc(size_t size); void* calloc(size_t num, size_t size); void free(void* ptr); -void reset_allocator(void); +void lame_pool_free(void); // stdio.h typedef void FILE; @@ -181,16 +181,16 @@ int toupper(int c) { } // malloc.h -static uint8_t memory_pool[MEMORY_POOL_SIZE]; -static size_t memory_offset = 0; +static uint8_t s_lame_pool[LAME_POOL_SIZE]; +static size_t s_lame_memory_use = 0; void* malloc(size_t size) { - if (memory_offset + size > MEMORY_POOL_SIZE) { + if (s_lame_memory_use + size > LAME_POOL_SIZE) { return (void*)0; } - void* ptr = &memory_pool[memory_offset]; - memory_offset += size; + void* ptr = &s_lame_pool[s_lame_memory_use]; + s_lame_memory_use += size; return ptr; } @@ -209,8 +209,8 @@ void* calloc(size_t num, size_t size) { void free(void* ptr) {} -void reset_allocator(void) { - memory_offset = 0; +void lame_pool_free(void) { + s_lame_memory_use = 0; } // stdio.h diff --git a/lib/refal05rts.c b/lib/refal05rts.c index 9532caa..0c71fca 100644 --- a/lib/refal05rts.c +++ b/lib/refal05rts.c @@ -420,6 +420,10 @@ static void ensure_memory(void) { static void free_memory(void) { + #ifdef LAMELIB + lame_pool_free(); + #endif /* LAMELIB */ + while (s_pool != 0) { struct memory_chunk *next = s_pool->next; free(s_pool); @@ -1338,9 +1342,81 @@ static void dump_buried(void) { } -int main() { - // s_argc = argc; - // s_argv = argv; +void reset_static_vars() { + s_end_free_list = (struct r05_node ) {0}; + + s_begin_free_list = (struct r05_node) { + 0, &s_end_free_list, R05_DATATAG_ILLEGAL, { '\0' } + }; + s_end_free_list = (struct r05_node ) { + &s_begin_free_list, 0, R05_DATATAG_ILLEGAL, { '\0' } + }; + + s_free_ptr = &s_end_free_list; + + s_memory_use = 0; + + s_pool = NULL; + s_stack_ptr = NULL; + + s_start_program_time = 0; + s_start_pattern_match_time = 0; + s_total_pattern_match_time = 0; + s_start_building_result_time = 0; + s_total_building_result_time = 0; + s_total_copy_tevar_time = 0; + s_total_match_repeated_tvar_time = 0; + s_total_match_repeated_evar_time = 0; + s_start_e_loop = 0; + s_total_e_loop = 0; + s_total_match_repeated_tvar_time_outside_e = 0; + s_total_match_repeated_evar_time_outside_e = 0; + + s_in_generated = 0; + s_in_e_loop = 0; + + #ifdef R05_PROFILER + s_profiled_functions = NULL; + #endif /* R05_PROFILER */ + + s_step_counter = 0; + + s_end_view_field = (struct r05_node) {0}; + + s_begin_view_field = (struct r05_node) { + 0, &s_end_view_field, R05_DATATAG_ILLEGAL, { '\0' } + }; + s_end_view_field = (struct r05_node) { + &s_begin_view_field, 0, R05_DATATAG_ILLEGAL, { '\0' } + }; + + s_stack_ptr = NULL; + + s_step_counter = 0; + + s_arg_begin = NULL; + s_arg_end = NULL; + + s_argv = 0; + s_argc = 0; + + s_end_buried = (struct r05_node) {0}; + + s_begin_buried = (struct r05_node ) { + 0, &s_end_buried, R05_DATATAG_ILLEGAL, { '\0' } + }; + s_end_buried = (struct r05_node) { + &s_begin_buried, 0, R05_DATATAG_ILLEGAL, { '\0' } + }; +} + +int main(int argc, char** argv) { +#ifdef LAMELIB + reset_static_vars(); +#endif + + s_argc = argc; + s_argv = argv; init_view_field(); start_profiler(); diff --git a/lib/refal05rts.h b/lib/refal05rts.h index 5dec1e7..a53cb09 100644 --- a/lib/refal05rts.h +++ b/lib/refal05rts.h @@ -13,7 +13,9 @@ extern "C" { #endif /* __cplusplus */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#ifdef LAMELIB +# define R05_NORETURN +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L # define R05_NORETURN _Noreturn # define R05_NORETURN_DEFINED #elif defined(__cplusplus) && __cplusplus >= 201103L