Skip to content

Commit

Permalink
Map in/is_member now behaves more like list in/is_member.
Browse files Browse the repository at this point in the history
  • Loading branch information
toddsundsted committed Jul 20, 2011
1 parent e9c53f5 commit 8e3f210
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 53 deletions.
20 changes: 10 additions & 10 deletions Makefile.in
Expand Up @@ -29,7 +29,7 @@ CFLAGS = -O
YFLAGS = -d
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c

CSRCS = ast.c code_gen.c db_file.c db_io.c db_objects.c \
CSRCS = ast.c code_gen.c collection.c db_file.c db_io.c db_objects.c \
db_properties.c db_verbs.c decompile.c disassemble.c \
eval_env.c eval_vm.c exceptions.c execute.c extensions.c \
functions.c json.c keywords.c list.c log.c malloc.c map.c \
Expand All @@ -52,15 +52,15 @@ OPT_CSRCS = gnu-malloc.c $(OPT_NET_SRCS)

YSRCS = parser.y

HDRS = ast.h bf_register.h code_gen.h db.h db_io.h db_private.h \
decompile.h db_tune.h disassemble.h eval_env.h eval_vm.h \
exceptions.h execute.h functions.h getpagesize.h json.h \
keywords.h list.h log.h map.h match.h md5.h name_lookup.h \
network.h net_mplex.h net_multi.h net_proto.h numbers.h \
opcode.h options.h parse_cmd.h parser.h pattern.h program.h \
quota.h random.h ref_count.h regexpr.h server.h storage.h \
streams.h structures.h str_intern.h sym_table.h tasks.h \
timers.h tokens.h unparse.h utils.h verbs.h version.h \
HDRS = ast.h bf_register.h code_gen.h collection.h db.h db_io.h \
db_private.h decompile.h db_tune.h disassemble.h eval_env.h \
eval_vm.h exceptions.h execute.h functions.h getpagesize.h \
json.h keywords.h list.h log.h map.h match.h md5.h \
name_lookup.h network.h net_mplex.h net_multi.h net_proto.h \
numbers.h opcode.h options.h parse_cmd.h parser.h pattern.h \
program.h quota.h random.h ref_count.h regexpr.h server.h \
storage.h streams.h structures.h str_intern.h sym_table.h \
tasks.h timers.h tokens.h unparse.h utils.h verbs.h version.h \
yajl_alloc.h yajl_buf.h yajl_bytestack.h yajl_common.h \
yajl_encode.h yajl_gen.h yajl_lex.h yajl_parse.h \
yajl_parser.h yajl_version.h
Expand Down
1 change: 1 addition & 0 deletions bf_register.h
Expand Up @@ -15,6 +15,7 @@
Pavel@Xerox.Com
*****************************************************************************/

extern void register_collection(void);
extern void register_disassemble(void);
extern void register_extensions(void);
extern void register_execute(void);
Expand Down
94 changes: 94 additions & 0 deletions collection.c
@@ -0,0 +1,94 @@
/******************************************************************************
Copyright (c) 1992, 1995, 1996 Xerox Corporation. All rights reserved.
Portions of this code were written by Stephen White, aka ghond.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
Pavel Curtis
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA 94304
Pavel@Xerox.Com
*****************************************************************************/

#include "bf_register.h"
#include "collection.h"
#include "functions.h"
#include "list.h"
#include "map.h"
#include "utils.h"

struct ismember_data {
int i;
Var value;
int case_matters;
};

static int
do_map_iteration(Var key, Var value, void *data, int first)
{
struct ismember_data *ismember_data = (struct ismember_data *)data;

if (equality(value, ismember_data->value, ismember_data->case_matters)) {
return ismember_data->i;
}

ismember_data->i++;

return 0;
}

int
ismember(Var lhs, Var rhs, int case_matters)
{
if (rhs.type == TYPE_LIST) {
int i;

for (i = 1; i <= rhs.v.list[0].v.num; i++) {
if (equality(lhs, rhs.v.list[i], case_matters)) {
return i;
}
}

return 0;
} else if (rhs.type == TYPE_MAP) {
struct ismember_data ismember_data;

ismember_data.i = 1;
ismember_data.value = lhs;
ismember_data.case_matters = case_matters;

return mapforeach(rhs, do_map_iteration, &ismember_data);
} else {
return 0;
}
}

/**** built in functions ****/

static package
bf_is_member(Var arglist, Byte next, void *vdata, Objid progr)
{
Var r;
Var rhs = arglist.v.list[2];

if (rhs.type != TYPE_LIST && rhs.type != TYPE_MAP) {
free_var(arglist);
return make_error_pack(E_INVARG);
}

r.type = TYPE_INT;
r.v.num = ismember(arglist.v.list[1], rhs, 1);
free_var(arglist);
return make_var_pack(r);
}

void
register_collection(void)
{
register_function("is_member", 2, 2, bf_is_member, TYPE_ANY, TYPE_ANY);
}
20 changes: 20 additions & 0 deletions collection.h
@@ -0,0 +1,20 @@
/******************************************************************************
Copyright (c) 1992, 1995, 1996 Xerox Corporation. All rights reserved.
Portions of this code were written by Stephen White, aka ghond.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
Pavel Curtis
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA 94304
Pavel@Xerox.Com
*****************************************************************************/

#include "structures.h"

extern int ismember(Var value, Var list, int case_matters);
1 change: 1 addition & 0 deletions db_file.c
Expand Up @@ -24,6 +24,7 @@
#include "my-stdio.h"
#include "my-stdlib.h"

#include "collection.h"
#include "config.h"
#include "db.h"
#include "db_io.h"
Expand Down
1 change: 1 addition & 0 deletions db_properties.c
Expand Up @@ -19,6 +19,7 @@
* Routines for manipulating properties on DB objects
*****************************************************************************/

#include "collection.h"
#include "config.h"
#include "db.h"
#include "db_private.h"
Expand Down
1 change: 1 addition & 0 deletions execute.c
Expand Up @@ -17,6 +17,7 @@

#include "my-string.h"

#include "collection.h"
#include "config.h"
#include "db.h"
#include "db_io.h"
Expand Down
1 change: 1 addition & 0 deletions functions.c
Expand Up @@ -44,6 +44,7 @@ typedef void (*registry) ();

static registry bi_function_registries[] =
{
register_collection,
register_disassemble,
register_extensions,
register_execute,
Expand Down
39 changes: 1 addition & 38 deletions list.c
Expand Up @@ -19,6 +19,7 @@
#include "my-string.h"

#include "bf_register.h"
#include "collection.h"
#include "config.h"
#include "exceptions.h"
#include "functions.h"
Expand Down Expand Up @@ -84,26 +85,6 @@ setremove(Var list, Var value)
}
}

int
ismember(Var lhs, Var rhs, int case_matters)
{
if (rhs.type == TYPE_LIST) {
int i;

for (i = 1; i <= rhs.v.list[0].v.num; i++) {
if (equality(lhs, rhs.v.list[i], case_matters)) {
return i;
}
}

return 0;
} else if (rhs.type == TYPE_MAP) {
return maplookup(rhs, lhs, NULL, case_matters);
} else {
return 0;
}
}

Var
listset(Var list, Var value, int pos)
{
Expand Down Expand Up @@ -610,23 +591,6 @@ bf_equal(Var arglist, Byte next, void *vdata, Objid progr)
return make_var_pack(r);
}

static package
bf_is_member(Var arglist, Byte next, void *vdata, Objid progr)
{
Var r;
Var rhs = arglist.v.list[2];

if (rhs.type != TYPE_LIST && rhs.type != TYPE_MAP) {
free_var(arglist);
return make_error_pack(E_INVARG);
}

r.type = TYPE_INT;
r.v.num = ismember(arglist.v.list[1], rhs, 1);
free_var(arglist);
return make_var_pack(r);
}

static package
bf_strsub(Var arglist, Byte next, void *vdata, Objid progr)
{ /* (source, what, with [, case-matters]) */
Expand Down Expand Up @@ -1271,7 +1235,6 @@ register_list(void)
register_function("listset", 3, 3, bf_listset,
TYPE_LIST, TYPE_ANY, TYPE_INT);
register_function("equal", 2, 2, bf_equal, TYPE_ANY, TYPE_ANY);
register_function("is_member", 2, 2, bf_is_member, TYPE_ANY, TYPE_ANY);

/* string */
register_function("tostr", 0, -1, bf_tostr);
Expand Down
1 change: 0 additions & 1 deletion list.h
Expand Up @@ -24,7 +24,6 @@ extern Var listdelete(Var list, int pos);
extern Var listset(Var list, Var value, int pos);
extern Var listrangeset(Var list, int from, int to, Var value);
extern Var listconcat(Var first, Var second);
extern int ismember(Var value, Var list, int case_matters);
extern Var setadd(Var list, Var value);
extern Var setremove(Var list, Var value);
extern Var sublist(Var list, int lower, int upper);
Expand Down
1 change: 1 addition & 0 deletions objects.c
Expand Up @@ -15,6 +15,7 @@
Pavel@Xerox.Com
*****************************************************************************/

#include "collection.h"
#include "db.h"
#include "db_io.h"
#include "exceptions.h"
Expand Down
13 changes: 9 additions & 4 deletions test/test_map.rb
Expand Up @@ -51,17 +51,22 @@ def test_that_length_returns_the_number_of_entries_in_a_map
end
end

def test_that_is_member_and_in_return_true_if_key_is_in_a_map
def test_that_is_member_and_in_return_true_if_value_is_in_a_map
run_test_as('programmer') do
x = simplify(command(%Q|; return ["3" -> "3", "1" -> "1", "4" -> "4", "5" -> "5", "9" -> "9", "2" -> "2"];|))
assert_equal 1, is_member("5", x)
assert_equal 5, is_member("5", x)
assert_equal 0, is_member(5, x)
assert_equal(1, simplify(command %|; return "2" in #{value_ref(x)};|))
assert_equal(2, simplify(command %|; return "2" in #{value_ref(x)};|))
assert_equal(0, simplify(command %|; return 2 in #{value_ref(x)};|))
# however, `is_member' is case-sensitive
y = simplify(command(%Q|; return ["FOO" -> "BAR"];|))
assert_equal 0, is_member("bar", y)
assert_equal(1, simplify(command %|; return "bar" in #{value_ref(y)};|))
# "foo" doesn't work (in any case)
assert_equal 0, is_member("foo", y)
assert_equal(1, simplify(command %|; return "foo" in #{value_ref(y)};|))
assert_equal(0, simplify(command %|; return "foo" in #{value_ref(y)};|))
assert_equal 0, is_member("FOO", y)
assert_equal(0, simplify(command %|; return "FOO" in #{value_ref(y)};|))
end
end

Expand Down

0 comments on commit 8e3f210

Please sign in to comment.