#include "crank.h" kstd::string_view crank_context::eval(kstd::string_view code) { auto ret = eval_no_copy(copy(code)); return ret; } kstd::string_view identity(kstd::string_view args, crank_context& ctx) { return args; } kstd::string_view set(kstd::string_view args, crank_context& ctx) { args = skip_whitespace(args); auto key = extract_token(args); auto value = skip_linearspace(kstd::string_view(args.begin()+key.size(),args.end())); return ctx.store(key,value); } bool istokenok(int m) { return ( isalpha(m) || isdigit(m) || m=='$' || m=='-' || m=='_' ); } bool islinearspace(int m) { return ( m==' ' || m=='\t' ); } kstd::string_view skip_whitespace(kstd::string_view code) { auto m = code.begin(); while(m kstd::string_view extract_bounded(kstd::string_view code) { auto m = code.begin(); while(m(code); } kstd::string_view extract_subcommand(kstd::string_view code) { return extract_bounded<']'>(code); } kstd::string_view extract_string(kstd::string_view code) { auto m = code.begin(); while(m(code); } kstd::string_view crank_context::execute_command(kstd::string_view code) { code = copy_replace(code); auto token = extract_token(code); auto symbol = get_symbol(token); auto args = skip_linearspace(kstd::string_view(code.begin()+token.size(),code.end())); if(symbol.size()) { if(symbol[0]=='@') { symbol = skip_linearspace(kstd::string_view(symbol.begin()+1, symbol.end())); while(istokenok(args[0])) { auto argname = extract_token(symbol); symbol = skip_linearspace(kstd::string_view(symbol.begin()+argname.size(), symbol.end())); auto argvalue = kstd::string_view(); if(args[0]=='{') { argvalue=extract_array(kstd::string_view(args.begin()+1, args.end())); args = skip_linearspace(kstd::string_view(args.begin()+argvalue.size()+2, args.end())); } else if(args[0]=='[') { argvalue=crank_context::execute_command(extract_subcommand(kstd::string_view(args.begin()+1, args.end()))); args = skip_linearspace(kstd::string_view(args.begin()+argvalue.size()+2, args.end())); } else if(args[0]=='"') { argvalue=extract_string(kstd::string_view(args.begin()+1, args.end())); args = skip_linearspace(kstd::string_view(args.begin()+argvalue.size()+2, args.end())); } else { argvalue=extract_token(kstd::string_view(args.begin()+1, args.end())); args = skip_linearspace(kstd::string_view(args.begin()+argvalue.size(), args.end())); } store(argname,argvalue); } symbol = extract_array(symbol); auto command = extract_command(symbol); auto ret = kstd::string_view(); while(command.size()) { ret = execute_command(command); symbol = kstd::string_view(symbol.begin()+command.size(),symbol.end()); command = extract_command(symbol); } return ret; } else { return symbol; } } else { return get_native(token)(args,this); } } kstd::string_view crank_context::eval_no_copy(kstd::string_view code) { auto command = extract_command(code); auto ret = kstd::string_view();; while(command.size()) { ret = execute_command(command); code = kstd::string_view(code.begin()+command.size(),code.end()); command = extract_command(code); } return ret; }