Skip to content

Commit

Permalink
Merge pull request #199 from sparkprime/extensions
Browse files Browse the repository at this point in the history
Extend native functions to all primitive types
  • Loading branch information
sparkprime committed May 30, 2016
2 parents 49ea2f4 + c205b5d commit 336111a
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 120 deletions.
95 changes: 27 additions & 68 deletions core/BUILD
Original file line number Diff line number Diff line change
@@ -1,104 +1,63 @@
package(default_visibility = ["//visibility:public"])

cc_library(
name = "common",
name = "libjsonnet",
srcs = [
"desugarer.cpp",
"formatter.cpp",
"lexer.cpp",
"libjsonnet.cpp",
"parser.cpp",
"static_analysis.cpp",
"string_utils.cpp",
"vm.cpp",
],
hdrs = [
"ast.h",
"desugarer.h",
"formatter.h",
"json.h",
"lexer.h",
"parser.h",
"state.h",
"static_analysis.h",
"static_error.h",
"string_utils.h",
"unicode.h",
"vm.h",
],
includes = ["."],
)

cc_library(
name = "lexer",
srcs = ["lexer.cpp"],
hdrs = ["lexer.h"],
deps = [
":common",
"//include:libjsonnet",
"//stdlib:std",
],
linkopts = ["-lm"],
includes = ["."],
)

cc_test(
name = "lexer_test",
srcs = ["lexer_test.cpp"],
deps = [
":lexer",
":libjsonnet",
# Note: On Ubuntu, apt-get install libgtest-dev google-mock
"//external:gtest_main",
],
)

cc_library(
name = "parser",
srcs = [
"desugarer.cpp",
"parser.cpp",
"string_utils.cpp",
],
hdrs = [
"desugarer.h",
"parser.h",
"string_utils.h",
],
deps = [
":common",
":lexer",
"//stdlib:std",
],
includes = [".", "../include"],
)

cc_test(
name = "parser_test",
srcs = ["parser_test.cpp"],
deps = [
":parser",
":libjsonnet",
"//external:gtest_main",
],
)

cc_library(
name = "jsonnet-common",
srcs = [
"desugarer.cpp",
"formatter.cpp",
"libjsonnet.cpp",
"static_analysis.cpp",
"vm.cpp",
],
hdrs = [
"desugarer.h",
"formatter.h",
"state.h",
"static_analysis.h",
"vm.h",
],
deps = [
":common",
":lexer",
":parser",
"//include:libjsonnet",
],
linkopts = ["-lm"],
includes = [".", "../include"],
)

cc_library(
name = "libjsonnet",
srcs = ["libjsonnet.cpp"],
deps = [
":jsonnet-common",
"//include:libjsonnet",
],
includes = [".", "../include"],
)

cc_test(
name = "libjsonnet_test",
srcs = ["libjsonnet_test.cpp"],
deps = [
":jsonnet-common",
":libjsonnet",
"//external:gtest_main",
],
)
8 changes: 7 additions & 1 deletion core/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@ limitations under the License.

struct JsonnetJsonValue {
enum Kind {
STRING
ARRAY, // Not implemented yet.
BOOL,
NULL_KIND,
NUMBER,
OBJECT, // Not implemented yet.
STRING,
};
Kind kind;
std::string string;
double number; // Also used for bool (0 and 1)
};

#endif
51 changes: 49 additions & 2 deletions core/libjsonnet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,28 @@ const char *jsonnet_json_extract_string(JsonnetVm *vm, const struct JsonnetJsonV
return v->string.c_str();
}

/** Convert the given UTF8 string to a JsonnetJsonValue.
*/
int jsonnet_json_extract_number(struct JsonnetVm *vm, const struct JsonnetJsonValue *v, double *out)
{
(void) vm;
if (v->kind != JsonnetJsonValue::NUMBER)
return 0;
*out = v->number;
return 1;
}

int jsonnet_json_extract_bool(struct JsonnetVm *vm, const struct JsonnetJsonValue *v)
{
(void) vm;
if (v->kind != JsonnetJsonValue::BOOL) return 2;
return v->number != 0;
}

int jsonnet_json_extract_null(struct JsonnetVm *vm, const struct JsonnetJsonValue *v)
{
(void) vm;
return v->kind == JsonnetJsonValue::NULL_KIND;
}

JsonnetJsonValue *jsonnet_json_make_string(JsonnetVm *vm, const char *v)
{
(void) vm;
Expand All @@ -70,6 +90,32 @@ JsonnetJsonValue *jsonnet_json_make_string(JsonnetVm *vm, const char *v)
return r;
}

JsonnetJsonValue *jsonnet_json_make_number(struct JsonnetVm *vm, double v)
{
(void) vm;
JsonnetJsonValue *r = new JsonnetJsonValue();
r->kind = JsonnetJsonValue::NUMBER;
r->number = v;
return r;
}

JsonnetJsonValue *jsonnet_json_make_bool(struct JsonnetVm *vm, int v)
{
(void) vm;
JsonnetJsonValue *r = new JsonnetJsonValue();
r->kind = JsonnetJsonValue::BOOL;
r->number = v != 0;
return r;
}

JsonnetJsonValue *jsonnet_json_make_null(struct JsonnetVm *vm)
{
(void) vm;
JsonnetJsonValue *r = new JsonnetJsonValue();
r->kind = JsonnetJsonValue::NULL_KIND;
return r;
}

struct JsonnetVm {
double gcGrowthTrigger;
unsigned maxStack;
Expand Down Expand Up @@ -497,6 +543,7 @@ static char *jsonnet_evaluate_snippet_aux(JsonnetVm *vm, const char *filename,
return from_string(vm, ss.str());
}

return nullptr; // Quiet, compiler.
}

static char *jsonnet_evaluate_file_aux(JsonnetVm *vm, const char *filename, int *error, EvalKind kind)
Expand Down
24 changes: 19 additions & 5 deletions core/libjsonnet_test_snippet.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ limitations under the License.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <libjsonnet.h>

struct JsonnetJsonValue *concat(void *ctx, const struct JsonnetJsonValue * const *argv, int *succ)
struct JsonnetJsonValue *native_concat(void *ctx, const struct JsonnetJsonValue * const *argv, int *succ)
{
struct JsonnetVm *vm = (struct JsonnetVm *)ctx;
const char *a = jsonnet_json_extract_string(vm, argv[0]);
const char *b = jsonnet_json_extract_string(vm, argv[1]);
if (a == NULL || b == NULL) {
struct JsonnetJsonValue *r = jsonnet_json_make_string(vm, "Bad params.");
*succ = 0;
return r;
return jsonnet_json_make_string(vm, "Bad params.");
}
char *str = malloc(strlen(a) + strlen(b) + 1);
sprintf(str, "%s%s", a, b);
Expand All @@ -38,18 +38,32 @@ struct JsonnetJsonValue *concat(void *ctx, const struct JsonnetJsonValue * const
return r;
}

struct JsonnetJsonValue *native_square(void *ctx, const struct JsonnetJsonValue * const *argv, int *succ)
{
struct JsonnetVm *vm = (struct JsonnetVm *)ctx;
double a;
if (!jsonnet_json_extract_number(vm, argv[0], &a)) {
*succ = 0;
return jsonnet_json_make_string(vm, "Bad param 'a'.");
}
*succ = 1;
return jsonnet_json_make_number(vm, a * a);
}

int main(int argc, const char **argv)
{
int error;
char *output;
struct JsonnetVm *vm;
const char *params[] = {"a", "b", NULL};
const char *params1[] = {"a", NULL};
const char *params2[] = {"a", "b", NULL};
if (argc != 2) {
fprintf(stderr, "libjsonnet_test_snippet <string>\n");
return EXIT_FAILURE;
}
vm = jsonnet_make();
jsonnet_native_callback(vm, "concat", concat, vm, params);
jsonnet_native_callback(vm, "concat", native_concat, vm, params2);
jsonnet_native_callback(vm, "square", native_square, vm, params1);
output = jsonnet_evaluate_snippet(vm, "snippet", argv[1], &error);
if (error) {
fprintf(stderr, "%s", output);
Expand Down
Loading

0 comments on commit 336111a

Please sign in to comment.