diff --git a/engine/slc.h b/engine/slc.h index c8b4238..d72ade8 100644 --- a/engine/slc.h +++ b/engine/slc.h @@ -535,7 +535,10 @@ static inline void slc( if(state == SLC_START) { SET_SLC_START } break; case SLC_DEF_NAME: - // TODO: Legyen nekem is fordítási idejű szó és sima!!! Optimalizációban sokat segít + // TODO: I must have : and :: (regular and compiled words) because when we generate threaded code, we cannot + // optimize word bodies with occurences of these-marked words as they might change program text and such! + // + // Examples for word definitions // : iff // () // asm{cmp eax, 0} @@ -545,51 +548,20 @@ static inline void slc( // asm{else@:} // [] // asm{endif@:} // @ az asm asm-nél jelentse: valami hash... - // end + // ; // - // - // De ezt vajon lehet? Szerintem ez ne lehessen / nem kell... - // - // : iff_not ()[]{} - // () - // asm{cmp eax, 0} - // asm{jnz else@} - // [] - // asm{else@:} // FIXME: nincs endif? - // {} - // end - // - // Called like - v1: + // Called like: // // #include "iff.slc" // - // iff(4 5 <) { + // iff(equal(a b)) { // 1 print // } [ // 0 print // ] // - // Called like - v2: - // - // #include "iff2.slc" - // - // iff_not(4 5 <) { - // 1 print - // } [ - // 0 print - // ] - // - // if(1) { - // A() - // } else { - // B() - // } - // - // Kontext-függő stack kell legyen? case-t csak switch-en belül írhatok (vagy mást jelent stb.) - // // Switch-case pl.: // - // // case (5) // itt nem lenne jó!!!! // switch(valami) { // case(0) { // csak itt // @@ -598,62 +570,13 @@ static inline void slc( // } // } // - // Emiatt a zárójelezős stack-re nem csak zárójelek kerüljenek!!! - // - // NIL - // switch( - // switch{ // Ezen a ponton kellhet ":@ switch{case" szót keresni - // switch{case( // TODO: Ez biztos nem kell! - // switch{case{ - // - // : switch - // () - // - // : switch@case // TODO: jobb syntax? Vagy kell-e oda a zárójel? Vagy csak "gyereke"? (stack helyett csak uccsó tárolva...???? Esetleg utolsó megelőző testvér is? - // () - // iff(=) { - // {} - // } // TODO: Ha van fallthrough GOTO-val - // - // Branch table-s fordítása is lehetséges két pass-ban pl... - // - // : switch - // () - // generate_ifs_for_cases@inherits // "megörökli" az én kontextusom... tehát az én (..) [..] és {..} - // // esetleg lehet neki is mondjuk {..} és csak az íródik felül.. ESETLEG! - // - // - // Ehhez képest factor-ban: - // - // [printtrue] [printfalse] 4 5 < if - // - // FORTH-ban: - // - // 12 = IF FILL-CARTON THEN - // - // Magyar forth-ba: - // - // 12 = VOLT_AKKOR KARTON_UJRATOLTES TORTENT - // - // :: VOLT_AKKOR IF - // - // :: IF - // asm{cmp eax, 0} - // asm{jnz else@} - // DECODE_WORD - // CALL_WORD - // asm{else@:} - // ; - // - // While és do-while is megy így.... - // - // XXX: De a for-ciklus??? Problémás... + // While and do-while loops also work similarily easily... but for loops first glance look harder... // // for(int i = 0; i < 50; ++i) { // .... // } // - // Szavak: + // SLC-words for this loop when parsed: // - for( // int // i @@ -667,15 +590,14 @@ static inline void slc( // ... // } // - // CSV(-szerű) cucc? Megoldás: + // One possible solution: abstract out a "delimiter parser" // - // - // :: for + // :: for // (*) // ( // ';' - // delim_parse // max 3 elemre parzol (vagy kevesebb) + // delim_parse // this is compile-time word but because we are too this reads not from here, but from after for!! // ( - // parse_from_stack + // parse_from_stack // this parses and runs code from the stack // ) // [ // asm("ciklusfelt@:") @@ -689,7 +611,9 @@ static inline void slc( // parse_from_stack // asm("jmp ciklusfelt@") // } - // // vissza is ad egy értéket a stackre, hogy "van-e még" adat? => tudok loop-olni (de max 1-2-3 féle kindra) + // // As retval, delim_parse returns to stack how many 'parts' were parsed! + // // If this is less than the blocks you used up, there were no more inputs + // drop // ) // { // asm("ciklusmag@:") @@ -704,17 +628,54 @@ static inline void slc( case SLC_DEF_BODY: break; case SLC_WORD_NAME: - // Words end with: + // Words might end with: // - any parentheses // - whitespaces: // -- followed by parentheses - // -- followed by word + // -- followed by non-parentheses + // - @ (which means variable access for that word) // - end of file - // return 42; - // if (..) [] {..}; - // if(1 + a < 42) + // + // Examples: + // - quit + // - if (..) {..} [..] + // - if(1 + a < 42) + // + // Why we need the "nesting stack" to contain word indices? Imagine the below SLC code... + // + // + // ifff(player@died) { + // // remove all weapons + // while(...) { + // .. + // } + // respawns[player@id]{--} + // } [ + // update_player + // ] + // + // Lets say 'if' is a compile-time word ('::'-kind defined) and thus we cannot just + // end up using the recursion call stack to solve when and what parts we parse anyways. + // However if we add the word indices to the "nesting stack" it will look like this: + // + // NIL + // if( + // if{ + // if{while( + // if{while{ + // if(respawns[ + // if(respawns{ + // if[ + // + // You can clearly see that now the stack exactly tells us on which words which "block" to continue! + // Rem.: This also works for "non-compile-time" regulard words and is simpler to implement it this + // way instead of implementing 'partial parses' in my opinion... maybe we need that anyways though... break; case SLC_WORD_VAR: + // Variable handing, like: + // player@xpos + // player@xpos(42) + // 42 player@xpos(_) // of course 42 was happening previously as an immediate! break; case SLC_SYN_ERROR: /* Recover from slc syntax errors at endlines for now */