diff --git a/js4g/StackMachine.cc b/js4g/StackMachine.cc index c340b3a..8a36414 100644 --- a/js4g/StackMachine.cc +++ b/js4g/StackMachine.cc @@ -31,7 +31,11 @@ namespace Dillo::Hydrogen::JavaScriptForge ::detail:: StackMachine_m if( C::debug ) std::cerr << "After processing stack is now: " << std::endl; if( C::debug ) for( const auto &element: stack ) { - std::cerr << std::get< std::string >( element ) << std::endl; + std::visit + ( + [&]( const auto &thing ) { std::cerr << thing << std::endl; }, + element + ); } } @@ -56,6 +60,21 @@ namespace Dillo::Hydrogen::JavaScriptForge ::detail:: StackMachine_m { if( C::debug ) std::cerr << "Processing token: " << word << std::endl; if( C::debug ) std::cerr << "Conditional depth is: " << conditionals.size() << std::endl; + if( C::debug ) + { + std::cerr << "The following cached named functions exist: " << std::endl; + for( const auto &name: wordNames ) + { + std::cerr << name << std::endl; + } + + std::cerr << "The following named functions exist: " << std::endl; + for( const auto &[ name, _ ]: words ) + { + std::cerr << name << std::endl; + } + } + const bool inConditional= not conditionals.empty(); if( false ); @@ -177,13 +196,15 @@ namespace Dillo::Hydrogen::JavaScriptForge ::detail:: StackMachine_m { if( definition.has_value() ) throw std::runtime_error{ "Nested definitions not supported." }; - definition= pop< std::string >(); + wordNames.push_back( pop< std::string >() ); + definition= wordNames.back(); + words[ wordNames.back() ]= {}; if( C::debug ) std::cerr << "Starting function definition for " << definition.value() << std::endl; } else if( word.at( 0 ) == '@' ) { - const std::string invoke{ word.substr( 1 ) }; + const auto invoke= word.substr( 1 ); if( not words.contains( invoke ) ) { throw std::runtime_error{ "Unknown keyword: `"s + std::string{ word } @@ -192,10 +213,6 @@ namespace Dillo::Hydrogen::JavaScriptForge ::detail:: StackMachine_m const auto &def= words.at( invoke ); - //std::copy( rbegin( def ), rend( def ), front_inserter( tokens ) ); - - //if( tokens.size() >= 1000 ) abort(); - tokenStack.emplace_back( def ); } else @@ -216,7 +233,7 @@ namespace Dillo::Hydrogen::JavaScriptForge ::detail:: StackMachine_m std::variant< std::string, StackMachine::Integer > StackMachine::pop() { - const auto rv= peek(); + const auto rv= std::move( peek() ); stack.pop_back(); return rv; } diff --git a/js4g/StackMachine.h b/js4g/StackMachine.h index 55d1979..5b77205 100644 --- a/js4g/StackMachine.h +++ b/js4g/StackMachine.h @@ -59,7 +59,8 @@ namespace Dillo::Hydrogen::JavaScriptForge ::detail:: StackMachine_m std::vector< Tokenizer > tokenStack; - std::map< std::string, std::deque< std::string > > words; + std::deque< std::string > wordNames; + std::map< std::string_view, std::deque< std::string > > words; // Which side of the current conditional to take. enum ConditionalState { If, Else, Skipped }; diff --git a/js4g/fib.lua b/js4g/fib.lua new file mode 100644 index 0000000..0c10b21 --- /dev/null +++ b/js4g/fib.lua @@ -0,0 +1,24 @@ +function fib( a ) + if a == 0 + then + return 0 + elseif a == 1 + then + return 1 + else + return fib( a - 1 ) + fib( a - 2 ) + end +end + +function do_fibs( cnt ) + if cnt > 0 + then + do_fibs( cnt - 1 ) + print( fib( cnt ) ) + else + print( fib( 0 ) ) + end +end + + +do_fibs( 38 )