Skip to content

Commit

Permalink
Added bind
Browse files Browse the repository at this point in the history
  • Loading branch information
flynnzac committed Nov 29, 2023
1 parent eb56239 commit 6606f30
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 13 deletions.
31 changes: 20 additions & 11 deletions src/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,20 +392,23 @@ mark_do_not_free (object* obj, unsigned long hash_name)
* @return pointer to data value at final slot location
*/
data*
get_by_levels (object* reg, unsigned long* hash, int levels, int* is_slot, char** name)
get_by_levels (object* reg, unsigned long* hash, int levels, int* is_slot, char** name, bool error_on_not_found)
{
slot sl;
sl.name = name[0];
sl.key = hash[0];
data* d = get(reg, &sl, 1);
if (d == NULL)
{
char* msg = malloc(sizeof(char)*
(strlen("Value at slot / not found.")
+ strlen(name[0]) + 1));
sprintf(msg, "Value at slot /%s not found.", name[0]);
do_error(msg, reg->task->task);
free(msg);
if (error_on_not_found)
{
char* msg = malloc(sizeof(char)*
(strlen("Value at slot / not found.")
+ strlen(name[0]) + 1));
sprintf(msg, "Value at slot /%s not found.", name[0]);
do_error(msg, reg->task->task);
free(msg);
}
}
else if (d->type != Object && levels > 1)
{
Expand All @@ -417,8 +420,11 @@ get_by_levels (object* reg, unsigned long* hash, int levels, int* is_slot, char*
{
if (d == NULL)
{
do_error("Slot not found in object.",
reg->task->task);
if (error_on_not_found)
{
do_error("Slot not found in object.",
reg->task->task);
}
return NULL;
}

Expand Down Expand Up @@ -455,8 +461,11 @@ get_by_levels (object* reg, unsigned long* hash, int levels, int* is_slot, char*

if (d == NULL)
{
do_error("Slot not found in object.",
reg->task->task);
if (error_on_not_found)
{
do_error("Slot not found in object.",
reg->task->task);
}
return NULL;
}

Expand Down
26 changes: 26 additions & 0 deletions src/operator.pshm
Original file line number Diff line number Diff line change
Expand Up @@ -4124,6 +4124,28 @@ op_infix (arg a, object* obj)
ret_ans(obj, result);
}

void
op_bind (arg a, object* obj)
{
#op=bind@
#length=2@
##CHECK_ARGS~$;

#num=1@
#type=Instruction@
##GETARG~$;

statement* s = ((instruction*) arg1->data)->stmt;

object* env = new_object(NULL, new_hash_size(a.length / 2 + 1),
obj->task);

bool error = object_from_args(a, env, 2, obj->task->task);
if (!error)
replace_all_non_literals(s, env);

}


void
add_basic_ops (object* obj)
Expand Down Expand Up @@ -4310,6 +4332,10 @@ add_basic_ops (object* obj)

assign_op(&d, op_help, NULL, NULL, 0);
set(obj,d,"help",1);

assign_op(&d, op_bind, NULL, NULL, 0);
set(obj,d,"bind",1);


/* String operations */

Expand Down
6 changes: 5 additions & 1 deletion src/slobil.h
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ int*
copy_isslot (int* is_slot, int levels);

data*
get_by_levels (object* reg, unsigned long* hash, int levels, int* is_slot, char** name);
get_by_levels (object* reg, unsigned long* hash, int levels, int* is_slot, char** name, bool error_on_not_found);

const char*
str_type (data_type type);
Expand Down Expand Up @@ -655,6 +655,10 @@ object_next_iter (object_iter* iter);
slot
make_slot(char* name);

void
replace_all_non_literals(statement* stmt, object* obj);



#ifdef GARBAGE
#define GC_PTHREADS
Expand Down
38 changes: 37 additions & 1 deletion src/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ execute_statement (statement* s, object* reg)
e->hash_name,
e->levels,
e->is_slot,
e->name);
e->name,
true);

}
}
Expand Down Expand Up @@ -240,3 +241,38 @@ execute_code (statement* s, object* reg)
is_error(error, reg->task->task);

}

void
replace_all_non_literals(statement* stmt, object* obj)
{
statement* s = stmt;
while (s != NULL)
{
element* el = s->head;
while (el != NULL)
{
if (el->statement)
{
replace_all_non_literals(el->s, obj);
}
else if (!el->literal)
{
data* d = get_by_levels(obj,
el->hash_name,
el->levels,
el->is_slot,
el->name,
false);

if (d != NULL)
{
el->data = copy_data(d);
el->literal = 1;
}
}

el = el->right;
}
s = s->right;
}
}

0 comments on commit 6606f30

Please sign in to comment.