Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3888e96c9 |
112
source/cell.c
112
source/cell.c
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "cell.h"
|
||||
#include "cell_internal.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
#define ENGINE "internal/engine.cm"
|
||||
#define CELL_SHOP_DIR ".cell"
|
||||
@@ -105,35 +104,6 @@ static char* load_core_file(const char *filename, size_t *out_size) {
|
||||
return data;
|
||||
}
|
||||
|
||||
static int print_json_errors(const char *json) {
|
||||
if (!json) return 0;
|
||||
cJSON *root = cJSON_Parse(json);
|
||||
if (!root) return 0;
|
||||
cJSON *errors = cJSON_GetObjectItemCaseSensitive(root, "errors");
|
||||
if (!cJSON_IsArray(errors) || cJSON_GetArraySize(errors) == 0) {
|
||||
cJSON_Delete(root);
|
||||
return 0;
|
||||
}
|
||||
const char *filename = "<unknown>";
|
||||
cJSON *fname = cJSON_GetObjectItemCaseSensitive(root, "filename");
|
||||
if (cJSON_IsString(fname))
|
||||
filename = fname->valuestring;
|
||||
cJSON *e;
|
||||
cJSON_ArrayForEach(e, errors) {
|
||||
const char *msg = cJSON_GetStringValue(
|
||||
cJSON_GetObjectItemCaseSensitive(e, "message"));
|
||||
cJSON *line = cJSON_GetObjectItemCaseSensitive(e, "line");
|
||||
cJSON *col = cJSON_GetObjectItemCaseSensitive(e, "column");
|
||||
if (msg && cJSON_IsNumber(line) && cJSON_IsNumber(col))
|
||||
fprintf(stderr, "%s:%d:%d: error: %s\n",
|
||||
filename, (int)line->valuedouble, (int)col->valuedouble, msg);
|
||||
else if (msg)
|
||||
fprintf(stderr, "%s: error: %s\n", filename, msg);
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the core path for use by scripts
|
||||
const char* cell_get_core_path(void) {
|
||||
return core_path;
|
||||
@@ -415,20 +385,16 @@ int cell_init(int argc, char **argv)
|
||||
|
||||
char *json = JS_AST(ctx, script, strlen(script), filename);
|
||||
if (json) {
|
||||
int has_errors = print_json_errors(json);
|
||||
printf("%s\n", json);
|
||||
free(json);
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return has_errors ? 1 : 0;
|
||||
} else {
|
||||
printf("Failed to parse AST\n");
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return json ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Check for --tokenize flag to output token array JSON */
|
||||
@@ -476,20 +442,16 @@ int cell_init(int argc, char **argv)
|
||||
|
||||
char *json = JS_Tokenize(ctx, script, strlen(script), filename);
|
||||
if (json) {
|
||||
int has_errors = print_json_errors(json);
|
||||
printf("%s\n", json);
|
||||
free(json);
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return has_errors ? 1 : 0;
|
||||
} else {
|
||||
printf("Failed to tokenize\n");
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return json ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Check for --mach flag to output machine code JSON */
|
||||
@@ -544,25 +506,10 @@ int cell_init(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (print_json_errors(ast_json)) {
|
||||
free(ast_json);
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
|
||||
if (mach_json) {
|
||||
if (print_json_errors(mach_json)) {
|
||||
free(mach_json);
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
printf("%s\n", mach_json);
|
||||
free(mach_json);
|
||||
} else {
|
||||
@@ -627,25 +574,10 @@ int cell_init(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (print_json_errors(ast_json)) {
|
||||
free(ast_json);
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
|
||||
if (mach_json) {
|
||||
if (print_json_errors(mach_json)) {
|
||||
free(mach_json);
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
JS_DumpRegisterMach(ctx, mach_json, JS_NULL);
|
||||
free(mach_json);
|
||||
} else {
|
||||
@@ -659,6 +591,8 @@ int cell_init(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* Check for --mach-run flag to generate and run machine code through register VM */
|
||||
fprintf(stderr, "DEBUG: argc=%d argv[1]=%s\n", argc, argc > 1 ? argv[1] : "NULL");
|
||||
fflush(stderr);
|
||||
if (argc >= 3 && strcmp(argv[1], "--mach-run") == 0) {
|
||||
const char *script_or_file = argv[2];
|
||||
char *script = NULL;
|
||||
@@ -693,7 +627,7 @@ int cell_init(int argc, char **argv)
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
JSContext *ctx = JS_NewContext(rt);
|
||||
JSContext *ctx = JS_NewContextWithHeapSize(rt, 1024 * 1024); /* 1MB heap for register VM */
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
JS_FreeRuntime(rt);
|
||||
@@ -711,14 +645,6 @@ int cell_init(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (print_json_errors(ast_json)) {
|
||||
free(ast_json);
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Generate machine code */
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
@@ -731,16 +657,12 @@ int cell_init(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (print_json_errors(mach_json)) {
|
||||
free(mach_json);
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Execute through register VM */
|
||||
fprintf(stderr, "DEBUG: About to execute mach code\n");
|
||||
fflush(stderr);
|
||||
JSValue result = JS_IntegrateRegister(ctx, mach_json, JS_NULL);
|
||||
fprintf(stderr, "DEBUG: Execution done, result tag=%d\n", (int)(result >> 48));
|
||||
fflush(stderr);
|
||||
free(mach_json);
|
||||
|
||||
int exit_code = 0;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
extern int cell_init(int argc, char **argv);
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
fprintf(stderr, "MAIN: starting\n");
|
||||
fflush(stderr);
|
||||
return cell_init(argc, argv);
|
||||
}
|
||||
1209
source/quickjs.c
1209
source/quickjs.c
File diff suppressed because it is too large
Load Diff
392
source/suite.c
392
source/suite.c
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
#include "quickjs.h"
|
||||
#include "cJSON.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
@@ -2133,360 +2132,6 @@ TEST(cell_module_string_constant) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
ERROR RECOVERY TESTS - Helper macros
|
||||
============================================================================ */
|
||||
|
||||
#define ASSERT_HAS_ERRORS(json_str, min_count) do { \
|
||||
cJSON *_root = cJSON_Parse(json_str); \
|
||||
ASSERT_MSG(_root != NULL, "failed to parse JSON output"); \
|
||||
cJSON *_errs = cJSON_GetObjectItem(_root, "errors"); \
|
||||
if (!_errs || !cJSON_IsArray(_errs) || cJSON_GetArraySize(_errs) < (min_count)) { \
|
||||
printf("[line %d: expected at least %d error(s), got %d] ", __LINE__, (min_count), \
|
||||
_errs && cJSON_IsArray(_errs) ? cJSON_GetArraySize(_errs) : 0); \
|
||||
cJSON_Delete(_root); \
|
||||
return 0; \
|
||||
} \
|
||||
cJSON_Delete(_root); \
|
||||
} while(0)
|
||||
|
||||
#define ASSERT_NO_ERRORS(json_str) do { \
|
||||
cJSON *_root = cJSON_Parse(json_str); \
|
||||
ASSERT_MSG(_root != NULL, "failed to parse JSON output"); \
|
||||
cJSON *_errs = cJSON_GetObjectItem(_root, "errors"); \
|
||||
if (_errs && cJSON_IsArray(_errs) && cJSON_GetArraySize(_errs) > 0) { \
|
||||
cJSON *_first = cJSON_GetArrayItem(_errs, 0); \
|
||||
const char *_msg = cJSON_GetStringValue(cJSON_GetObjectItem(_first, "message")); \
|
||||
printf("[line %d: expected no errors, got: %s] ", __LINE__, _msg ? _msg : "?"); \
|
||||
cJSON_Delete(_root); \
|
||||
return 0; \
|
||||
} \
|
||||
cJSON_Delete(_root); \
|
||||
} while(0)
|
||||
|
||||
#define ASSERT_ERROR_MSG_CONTAINS(json_str, substring) do { \
|
||||
cJSON *_root = cJSON_Parse(json_str); \
|
||||
ASSERT_MSG(_root != NULL, "failed to parse JSON output"); \
|
||||
cJSON *_errs = cJSON_GetObjectItem(_root, "errors"); \
|
||||
int _found = 0; \
|
||||
if (_errs && cJSON_IsArray(_errs)) { \
|
||||
cJSON *_e; \
|
||||
cJSON_ArrayForEach(_e, _errs) { \
|
||||
const char *_msg = cJSON_GetStringValue(cJSON_GetObjectItem(_e, "message")); \
|
||||
if (_msg && strstr(_msg, (substring))) { _found = 1; break; } \
|
||||
} \
|
||||
} \
|
||||
if (!_found) { \
|
||||
printf("[line %d: no error containing '%s'] ", __LINE__, (substring)); \
|
||||
cJSON_Delete(_root); \
|
||||
return 0; \
|
||||
} \
|
||||
cJSON_Delete(_root); \
|
||||
} while(0)
|
||||
|
||||
/* ============================================================================
|
||||
TOKENIZER ERROR TESTS
|
||||
============================================================================ */
|
||||
|
||||
TEST(tokenize_unterminated_string) {
|
||||
const char *src = "var x = \"hello";
|
||||
char *json = JS_Tokenize(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_Tokenize returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "unterminated string");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(tokenize_unterminated_template) {
|
||||
const char *src = "var x = `hello";
|
||||
char *json = JS_Tokenize(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_Tokenize returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "unterminated template");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(tokenize_unterminated_block_comment) {
|
||||
const char *src = "var x /* comment";
|
||||
char *json = JS_Tokenize(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_Tokenize returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "unterminated block comment");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(tokenize_malformed_hex) {
|
||||
const char *src = "var x = 0x";
|
||||
char *json = JS_Tokenize(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_Tokenize returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "malformed hex");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(tokenize_malformed_binary) {
|
||||
const char *src = "var x = 0b";
|
||||
char *json = JS_Tokenize(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_Tokenize returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "malformed binary");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(tokenize_malformed_exponent) {
|
||||
const char *src = "var x = 1e+";
|
||||
char *json = JS_Tokenize(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_Tokenize returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "no digits after exponent");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(tokenize_valid_no_errors) {
|
||||
const char *src = "var x = 42";
|
||||
char *json = JS_Tokenize(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_Tokenize returned NULL");
|
||||
ASSERT_NO_ERRORS(json);
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
PARSER ERROR TESTS
|
||||
============================================================================ */
|
||||
|
||||
TEST(ast_missing_identifier_after_var) {
|
||||
const char *src = "var = 1";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "expected identifier");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_missing_initializer_def) {
|
||||
const char *src = "def x";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "missing initializer");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_recovery_continues_after_error) {
|
||||
const char *src = "var = 1; var y = 2";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_HAS_ERRORS(json, 1);
|
||||
/* Check that 'y' statement is present in the AST */
|
||||
ASSERT_MSG(strstr(json, "\"y\"") != NULL, "recovery failed: 'y' not in AST");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_valid_no_errors) {
|
||||
const char *src = "var x = 1; var y = 2";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_NO_ERRORS(json);
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
AST SEMANTIC ERROR TESTS
|
||||
============================================================================ */
|
||||
|
||||
TEST(ast_sem_assign_to_const) {
|
||||
const char *src = "def x = 5; x = 3";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "cannot assign to constant");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_sem_assign_to_arg) {
|
||||
const char *src = "function(x) { x = 5; }";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "cannot assign to constant");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_sem_redeclare_const) {
|
||||
const char *src = "def x = 1; def x = 2";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "cannot redeclare constant");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_sem_break_outside_loop) {
|
||||
const char *src = "break";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "outside of loop");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_sem_continue_outside_loop) {
|
||||
const char *src = "continue";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "outside of loop");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_sem_break_inside_loop_ok) {
|
||||
const char *src = "while (true) { break; }";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_NO_ERRORS(json);
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_sem_increment_const) {
|
||||
const char *src = "def x = 1; x++";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(json, "cannot assign to constant");
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_sem_shadow_var_ok) {
|
||||
const char *src = "var array = []; array";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_NO_ERRORS(json);
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_sem_var_assign_ok) {
|
||||
const char *src = "var x = 1; x = x + 1";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_NO_ERRORS(json);
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(ast_sem_nested_function_scope) {
|
||||
const char *src = "var x = 1; function f(x) { return x + 1; }";
|
||||
char *json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(json != NULL, "JS_AST returned NULL");
|
||||
ASSERT_NO_ERRORS(json);
|
||||
free(json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
CODEGEN/SEMANTIC ERROR TESTS
|
||||
============================================================================ */
|
||||
|
||||
TEST(mach_assign_to_const) {
|
||||
const char *src = "def x = 1; x = 2";
|
||||
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
ASSERT_MSG(mach_json != NULL, "JS_Mach returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(mach_json, "cannot assign to constant");
|
||||
free(mach_json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(mach_assign_to_arg) {
|
||||
const char *src = "function f(x) { x = 5 }";
|
||||
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
ASSERT_MSG(mach_json != NULL, "JS_Mach returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(mach_json, "cannot assign to function argument");
|
||||
free(mach_json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(mach_redeclare_const) {
|
||||
const char *src = "def x = 1; def x = 2";
|
||||
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
ASSERT_MSG(mach_json != NULL, "JS_Mach returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(mach_json, "cannot redeclare constant");
|
||||
free(mach_json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(mach_break_outside_loop) {
|
||||
const char *src = "break";
|
||||
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
ASSERT_MSG(mach_json != NULL, "JS_Mach returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(mach_json, "outside of loop");
|
||||
free(mach_json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(mach_continue_outside_loop) {
|
||||
const char *src = "continue";
|
||||
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
ASSERT_MSG(mach_json != NULL, "JS_Mach returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(mach_json, "outside of loop");
|
||||
free(mach_json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(mach_assign_unbound_var) {
|
||||
const char *src = "x = 42";
|
||||
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
ASSERT_MSG(mach_json != NULL, "JS_Mach returned NULL");
|
||||
ASSERT_ERROR_MSG_CONTAINS(mach_json, "not declared");
|
||||
free(mach_json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(mach_shadow_is_ok) {
|
||||
const char *src = "var array = []; array";
|
||||
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
ASSERT_MSG(mach_json != NULL, "JS_Mach returned NULL");
|
||||
ASSERT_NO_ERRORS(mach_json);
|
||||
free(mach_json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(mach_valid_no_errors) {
|
||||
const char *src = "var x = 1; x = x + 1";
|
||||
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
|
||||
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
ASSERT_MSG(mach_json != NULL, "JS_Mach returned NULL");
|
||||
ASSERT_NO_ERRORS(mach_json);
|
||||
free(mach_json);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
MAIN TEST RUNNER
|
||||
============================================================================ */
|
||||
@@ -2703,43 +2348,6 @@ int run_c_test_suite(JSContext *ctx)
|
||||
RUN_TEST(cell_module_roundtrip_execute);
|
||||
RUN_TEST(cell_module_string_constant);
|
||||
|
||||
printf("\nTokenizer Errors:\n");
|
||||
RUN_TEST(tokenize_unterminated_string);
|
||||
RUN_TEST(tokenize_unterminated_template);
|
||||
RUN_TEST(tokenize_unterminated_block_comment);
|
||||
RUN_TEST(tokenize_malformed_hex);
|
||||
RUN_TEST(tokenize_malformed_binary);
|
||||
RUN_TEST(tokenize_malformed_exponent);
|
||||
RUN_TEST(tokenize_valid_no_errors);
|
||||
|
||||
printf("\nParser Errors:\n");
|
||||
RUN_TEST(ast_missing_identifier_after_var);
|
||||
RUN_TEST(ast_missing_initializer_def);
|
||||
RUN_TEST(ast_recovery_continues_after_error);
|
||||
RUN_TEST(ast_valid_no_errors);
|
||||
|
||||
printf("\nAST Semantic Errors:\n");
|
||||
RUN_TEST(ast_sem_assign_to_const);
|
||||
RUN_TEST(ast_sem_assign_to_arg);
|
||||
RUN_TEST(ast_sem_redeclare_const);
|
||||
RUN_TEST(ast_sem_break_outside_loop);
|
||||
RUN_TEST(ast_sem_continue_outside_loop);
|
||||
RUN_TEST(ast_sem_break_inside_loop_ok);
|
||||
RUN_TEST(ast_sem_increment_const);
|
||||
RUN_TEST(ast_sem_shadow_var_ok);
|
||||
RUN_TEST(ast_sem_var_assign_ok);
|
||||
RUN_TEST(ast_sem_nested_function_scope);
|
||||
|
||||
printf("\nCodegen Errors:\n");
|
||||
RUN_TEST(mach_assign_to_const);
|
||||
RUN_TEST(mach_assign_to_arg);
|
||||
RUN_TEST(mach_redeclare_const);
|
||||
RUN_TEST(mach_break_outside_loop);
|
||||
RUN_TEST(mach_continue_outside_loop);
|
||||
RUN_TEST(mach_assign_unbound_var);
|
||||
RUN_TEST(mach_shadow_is_ok);
|
||||
RUN_TEST(mach_valid_no_errors);
|
||||
|
||||
printf("\n=================================\n");
|
||||
printf("Results: %d passed, %d failed\n", tests_passed, tests_failed);
|
||||
printf("=================================\n\n");
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
typeof 5
|
||||
@@ -1 +0,0 @@
|
||||
void 0
|
||||
Reference in New Issue
Block a user