static sl_node_base_t* regexp_expression(sl_parse_state_t* ps) { sl_token_t* re = expect_token(ps, SL_TOK_REGEXP); sl_token_t* opts = expect_token(ps, SL_TOK_REGEXP_OPTS); return sl_make_immediate_node(ps, sl_make_regexp(ps->vm, re->as.str.buff, re->as.str.len, opts->as.str.buff, opts->as.str.len)); }
static sl_node_base_t* unary_expression(sl_parse_state_t* ps) { sl_node_base_t* expr; sl_token_t* tok; switch(peek_token(ps)->type) { case SL_TOK_MINUS: tok = next_token(ps); expr = unary_expression(ps); return sl_make_send_node(ps, expr, sl_intern(ps->vm, "negate"), 0, NULL); case SL_TOK_TILDE: tok = next_token(ps); expr = unary_expression(ps); return sl_make_send_node(ps, expr, sl_intern2(ps->vm, tok->str), 0, NULL); case SL_TOK_NOT: next_token(ps); expr = unary_expression(ps); return sl_make_unary_node(ps, expr, SL_NODE_NOT); case SL_TOK_RETURN: tok = next_token(ps); if(!(ps->scope->flags & SL_PF_CAN_RETURN)) { error(ps, sl_make_cstring(ps->vm, "Can't return outside of a method or lambda"), tok); } switch(peek_token(ps)->type) { case SL_TOK_SEMICOLON: case SL_TOK_CLOSE_BRACE: case SL_TOK_CLOSE_TAG: /* in these case we want to allow for postfix control structures: */ case SL_TOK_IF: case SL_TOK_UNLESS: return sl_make_unary_node(ps, sl_make_immediate_node(ps, ps->vm->lib.nil), SL_NODE_RETURN); default: return sl_make_unary_node(ps, low_precedence_logical_expression(ps), SL_NODE_RETURN); } break; case SL_TOK_THROW: next_token(ps); return sl_make_unary_node(ps, low_precedence_logical_expression(ps), SL_NODE_THROW); case SL_TOK_USE: return use_expression(ps); default: return power_expression(ps); } }
static sl_node_base_t* primary_expression(sl_parse_state_t* ps) { sl_token_t* tok; sl_node_base_t* node; switch(peek_token(ps)->type) { case SL_TOK_INTEGER: tok = next_token(ps); return sl_make_immediate_node(ps, sl_integer_parse(ps->vm, tok->as.str.buff, tok->as.str.len)); case SL_TOK_FLOAT: return sl_make_immediate_node(ps, sl_make_float(ps->vm, next_token(ps)->as.dbl)); case SL_TOK_STRING: tok = next_token(ps); return sl_make_immediate_node(ps, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)); case SL_TOK_REGEXP: return regexp_expression(ps); case SL_TOK_CONSTANT: tok = next_token(ps); return sl_make_const_node(ps, NULL, sl_intern2(ps->vm, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len))); case SL_TOK_IDENTIFIER: tok = next_token(ps); return sl_make_var_node(ps, SL_NODE_VAR, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)); case SL_TOK_TRUE: next_token(ps); return sl_make_immediate_node(ps, ps->vm->lib._true); case SL_TOK_FALSE: next_token(ps); return sl_make_immediate_node(ps, ps->vm->lib._false); case SL_TOK_NIL: next_token(ps); return sl_make_immediate_node(ps, ps->vm->lib.nil); case SL_TOK_SELF: next_token(ps); return sl_make_self_node(ps); case SL_TOK_IVAR: tok = next_token(ps); node = sl_make_var_node(ps, SL_NODE_IVAR, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)); return node; case SL_TOK_CVAR: tok = next_token(ps); node = sl_make_var_node(ps, SL_NODE_CVAR, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)); return node; case SL_TOK_IF: case SL_TOK_UNLESS: return if_expression(ps); case SL_TOK_WHILE: case SL_TOK_UNTIL: return while_expression(ps); case SL_TOK_FOR: return for_expression(ps); case SL_TOK_CLASS: return class_expression(ps); case SL_TOK_DEF: return def_expression(ps); case SL_TOK_LAMBDA: return lambda_expression(ps); case SL_TOK_TRY: return try_expression(ps); case SL_TOK_OPEN_BRACKET: return array_expression(ps); case SL_TOK_OPEN_PAREN: return bracketed_expression(ps); case SL_TOK_OPEN_BRACE: return dict_expression(ps); case SL_TOK_NEXT: tok = next_token(ps); if(!(ps->scope->flags & SL_PF_CAN_NEXT_LAST)) { error(ps, sl_make_cstring(ps->vm, "next invalid outside loop"), tok); } return sl_make_singleton_node(ps, SL_NODE_NEXT); case SL_TOK_LAST: tok = next_token(ps); if(!(ps->scope->flags & SL_PF_CAN_NEXT_LAST)) { error(ps, sl_make_cstring(ps->vm, "last invalid outside loop"), tok); } return sl_make_singleton_node(ps, SL_NODE_LAST); case SL_TOK_RANGE_EX: next_token(ps); return sl_make_singleton_node(ps, SL_NODE_YADA_YADA); default: unexpected(ps, peek_token(ps)); return NULL; } }
static sl_node_base_t* static_string_expression(sl_parse_state_t* ps) { sl_token_t* tok = expect_token(ps, SL_TOK_STRING); return sl_make_immediate_node(ps, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)); }