- 🔭 I'm rewriting hedgehog
- 🌱 I’m currently learning LLVM.
- 📫 How to reach me: yangtau.me
yangtau / hedgehog Goto Github PK
View Code? Open in Web Editor NEWa toy programming language
License: MIT License
a toy programming language
License: MIT License
Compile tuple
Line 145 in 6c4314f
break;
default:
// TODO: Compile tuple
unimplemented_("TODO: tuple with length of %ld", tuple->len);
}
return 0;
aa450084736bfe7c2a75edfb9e7ab84b9e5f184b
splite id and value
Line 304 in 20f6c7b
}
static int compile_ast_node_value(struct compiler_context* ctx, void* _value) {
struct hg_value* val = _value;
int rc = 0;
if (VAL_IS_BOOL(*val)) {
chunk_write(ctx->chk, VAL_AS_BOOL(*val) ? OP_TRUE : OP_FALSE);
} else if (VAL_IS_OBJ(*val) && (VAL_AS_OBJ(*val)->type == HG_OBJ_SYMBOL)) {
// TODO: splite id and value
bool islocal;
int loc;
if ((loc = find_variable(ctx, *val, &islocal)) == -1) {
fprintf(stderr, "compile error: reference before definition `");
hg_value_write(*val, stderr, true);
fprintf(stderr, "`\n");
rc = -1;
} else {
chunk_write(ctx->chk, islocal ? OP_GET_LOCAL : OP_GET_STATIC);
chunk_write_word(ctx->chk, loc);
}
} else {
uint16_t loc = chunk_add_const(ctx->chk, *val);
chunk_write(ctx->chk, OP_GET_CONST);
chunk_write_word(ctx->chk, loc);
}
return rc;
}
static int compile_ast_node_stats(struct compiler_context* ctx, void* _stats) {
struct ast_node_array* stats = _stats;
int rc = 0;
for (size_t i = 0; i < stats->len; i++) {
rc |= compile_ast_node(ctx, stats->arr[i]);
}
return rc;
}
static int compile_ast_node_tuple(struct compiler_context* ctx, void* _tuple) {
struct ast_node_array* tuple = _tuple;
switch (tuple->len) {
case 0: // nil
chunk_write(ctx->chk, OP_NIL);
break;
case 1: // unpack if there is only one element in the tuple
compile_ast_node(ctx, tuple->arr[0]);
break;
default:
// TODO: Compile tuple
9bd8f0ab25866676cbf8cbffb3a8dae5f2cd26bd
Check the number of arguments while compiling fucntion call
Line 1 in 6c4314f
#include "compile.h"
#include "ast_node.h"
#include "common.h"
63505fc8e3f0bd66581ea231f0a5320877d347ca
free referrence to str
Line 428 in ac62e6b
void hg_ast_node_free(struct hg_ast_node* _node) {
if (_node == NULL)
return;
switch (_node->type) {
case AST_NODE_ASSIGNMENT: {
_raw_to(_node, struct hg_ast_assignment_stat, node);
hg_ast_node_free(node->exprs);
hg_ast_node_free(node->vars);
hg_free(node);
} break;
case AST_NODE_FOR: {
_raw_to(_node, struct hg_ast_for_stat, node);
hg_ast_node_free(node->params);
hg_ast_node_free(node->iterator);
hg_ast_node_free(node->block);
hg_free(node);
} break;
case AST_NODE_IF: {
_raw_to(_node, struct hg_ast_if_stat, node);
hg_ast_node_free(node->condition);
hg_ast_node_free(node->block);
hg_ast_node_free(node->else_block);
hg_free(node);
} break;
case AST_NODE_FUNC: {
_raw_to(_node, struct hg_ast_func_stat, node);
hg_ast_node_free(node->id);
hg_ast_node_free(node->params);
hg_ast_node_free(node->block);
hg_free(node);
} break;
case AST_NODE_BREAK: {
_raw_to(_node, struct hg_ast_break_stat, node);
hg_free(node);
} break;
case AST_NODE_CONTINUE: {
_raw_to(_node, struct hg_ast_continue_stat, node);
hg_free(node);
} break;
case AST_NODE_RETURN: {
_raw_to(_node, struct hg_ast_return_stat, node);
hg_ast_node_free(node->exprs);
hg_free(node);
} break;
case AST_NODE_CALL: {
_raw_to(_node, struct hg_ast_call_expr, node);
hg_ast_node_free(node->callable);
hg_ast_node_free(node->args);
hg_free(node);
} break;
case AST_NODE_FIELD: {
_raw_to(_node, struct hg_ast_field_expr, node);
hg_ast_node_free(node->prefix);
hg_ast_node_free(node->field);
hg_free(node);
} break;
case AST_NODE_INDEX: {
_raw_to(_node, struct hg_ast_index_expr, node);
hg_ast_node_free(node->prefix);
hg_ast_node_free(node->index);
hg_free(node);
} break;
case AST_NODE_FUNC_DEF: {
_raw_to(_node, struct hg_ast_func_def_expr, node);
hg_ast_node_free(node->params);
hg_ast_node_free(node->block);
hg_free(node);
} break;
case AST_NODE_BINARY_EXPR: {
_raw_to(_node, struct hg_ast_binary_expr, node);
hg_ast_node_free(node->left);
hg_ast_node_free(node->right);
hg_free(node);
} break;
case AST_NODE_UNARY_EXPR: {
_raw_to(_node, struct hg_ast_unary_expr, node);
hg_ast_node_free(node->expr);
hg_free(node);
} break;
case AST_NODE_TABLE: {
_raw_to(_node, struct hg_ast_table_expr, node);
hg_ast_node_free(node->entries);
hg_free(node);
} break;
case AST_NODE_TABLE_ENTRY: {
_raw_to(_node, struct hg_ast_table_entry, node);
hg_ast_node_free(node->key);
hg_ast_node_free(node->value);
hg_free(node);
} break;
case AST_NODE_LITERAL_STR: {
_raw_to(_node, struct hg_ast_literal, node);
// TODO: free referrence to str
hg_free(node);
} break;
case AST_NODE_LITERAL_ID: {
_raw_to(_node, struct hg_ast_literal, node);
// TODO: free referrence to str
hg_free(node);
} break;
case AST_NODE_LITERAL_BOOL: {
_raw_to(_node, struct hg_ast_literal, node);
hg_free(node);
} break;
case AST_NODE_LITERAL_INT: {
_raw_to(_node, struct hg_ast_literal, node);
hg_free(node);
} break;
case AST_NODE_LITERAL_FLOAT: {
_raw_to(_node, struct hg_ast_literal, node);
hg_free(node);
} break;
case AST_NODE_ARRAY: {
_raw_to(_node, struct hg_ast_node_array, node);
for (int i = 0; i < node->len; i++) {
hg_free(node->arr[i]);
}
hg_free(node);
} break;
default:
unreachable_();
}
}
static void _node_to_str(struct hg_ast_node* node, uint32_t indent,
struct hg_string_buffer* buffer) {
}
hg_char hg_ast_node_to_str(struct hg_ast_node* node, uint32_t indent) {
}
#undef _new
#undef _raw
#undef _raw_to
ndex 8066773..5c493a5 100644
++ b/src/ast.h
2e8ecae7a9268805af54f8630ce67bedf0e03554
Compile local Variables (set)
Line 185 in 6c4314f
chunk_write_word(chk, loc);
} else {
// TODO: Compile local Variables (set)
unimplemented_("local vars");
}
}
ndex fda2c94..e3322d8 100644
++ b/src/main.c
91d399340620a93cfecac286b360b7f8e523b33c
Compile local variable (get)
Line 101 in 6c4314f
} else {
// TODO: Compile local variable (get)
unimplemented_("local");
}
return 0;
eba01d4cc9186ffc23e6d97f60a2b907003b50b3
Create a constant value if all items in a collection are constant values
List
Tuple
Map
Line 146 in 5368dd8
}
// TODO: Create a constant value if all items in a collection are constant values
// - [ ] List
// - [ ] Tuple
// - [ ] Map
struct ast_node* ast_node_list_new(struct parser_state* p,
struct ast_node* args) {
assert(args == NULL || args->type == AST_NODE_ARGS);
73d5e8bfbba86cbdde9981713d345252bb525d03
make capacity be the power of 2
Line 76 in 6519bc6
}
void value_array_init_with_values(struct value_array* arr, int len,
const struct hg_value* values) {
arr->len = len;
arr->capacity = len; // TODO: make capacity be the power of 2
arr->values = array_alloc_(struct hg_value, len);
memcpy(arr->values, values, len * sizeof(struct hg_value));
}
void value_array_free(struct value_array* arr) {
array_free_(arr->values, struct hg_value, arr->capacity);
ndex 66fe506..746c3f5 100644
++ b/src/value.h
e328efb8e9c5be82f3f2fa681c800092979c11a4
make all object flexiable to avoid free and alloc twice for every object
Line 126 in 65e6e64
wrapper->mark = false;
wrapper->size = size;
wrapper->next = wrapper_list;
wrapper_list = wrapper;
return &wrapper->obj;
}
static void mark_obj(struct hg_object* obj);
static _force_inline_ void mark_list(struct hg_list* list) {
for (size_t i = 0; i < list->arr.len; i++) {
if (VAL_IS_OBJ(list->arr.values[i])) {
mark_obj(VAL_AS_OBJ(list->arr.values[i]));
}
}
}
static _force_inline_ void mark_map(struct hash_map* map) {
for (size_t i = 0; i < map->len; i++) {
if (VAL_IS_OBJ(map->entries[i].key)) {
mark_obj(VAL_AS_OBJ(map->entries[i].key));
}
if (VAL_IS_OBJ(map->entries[i].value)) {
mark_obj(VAL_AS_OBJ(map->entries[i].value));
}
}
}
static _force_inline_ void mark_set(struct hash_set* set) {
for (size_t i = 0; i < set->len; i++) {
if (VAL_IS_OBJ(set->items[i])) {
mark_obj(VAL_AS_OBJ(set->items[i]));
}
}
}
static void mark_obj(struct hg_object* obj) {
obj_wrapper* wrapper = obj2wrapper_(obj);
wrapper->mark = true;
switch (obj->type) {
case HG_OBJ_MAP:
mark_map((struct hash_map*)obj);
break;
case HG_OBJ_SET:
mark_set((struct hash_set*)obj);
break;
case HG_OBJ_LIST:
mark_list((struct hg_list*)obj);
break;
case HG_OBJ_FUNCTION:
case HG_OBJ_STRING:
case HG_OBJ_SYMBOL:
case HG_OBJ_TUPLE:
break;
}
}
static inline void mark() {
for (struct hg_value* p = vm->stack; p < vm->stack_top; p++) {
if (VAL_IS_OBJ(*p)) {
mark_obj(VAL_AS_OBJ(*p));
}
}
}
static inline void sweep() {
obj_wrapper** p = &wrapper_list;
while (*p) {
if (!(*p)->mark) {
obj_wrapper* t = *p;
*p = t->next;
// TODO: make all object flexiable to avoid free and alloc twice for every object
hg_obj_free_(&t->obj);
hg_realloc(t, t->size, 0);
} else {
(*p)->mark = true;
}
p = &(*p)->next;
}
}
void gc_clean() {
sweep();
}
#undef obj2wrapper_
ndex f31d7b8..c5a05df 100644
++ b/src/gc.h
4bbba866dd8a918a53c6373031417ecc6f644160
In the README an example for the creation of a module is given. Maybe I'm stupid, but I can't get this working.
Actually, none of the examples in the README are correct. The files in the examples dir are okay, except the most interesting one: closure.hg
Hello, it's me again.
In the former version there was a main() function available whith which you could create a normal executable, in order to test e.g. the examples. Could something like this be added again?
W.Boeke
isolate static area from chunk
statics
should not be in one function, it should be shared globally.
global variables area
constants area
Line 39 in a6851f5
size_t len;
size_t capacity;
// TODO: isolate static area from chunk
// `statics` should not be in one function, it should be shared globally.
struct value_array statics; // global variables area
struct value_array consts; // constants area
uint8_t* code;
ew file mode 100644
ndex 0000000..7eeaa85
++ b/src/function.c
4bf55410360abaa62acbccd41fbb48a8b212b060
replace hash_set_init with hash_set_new
to make it a hg_object type
Line 6 in e2425af
#define _HG_HASH_H_
#include "object.h"
#include "value.h"
// TODO: replace hash_set_init with hash_set_new
// to make it a hg_object type
#define HASH_INITIAL_SIZE (3u)
#define HASH_LOAD_FACTOR (0.75)
// the maximum number of tombstones is capacity*HASH_TOMB_FACTOR
ab4db4af90d1ff27a1345a504c29236a38a9b9cd
the result of calling index_set
will be on the stack
Line 469 in 7cdec3d
for (int i = vars->len - 1; i >= 0; i--) {
if (vars->arr[i]->type == AST_NODE_INDEX) {
// TODO: the result of calling `index_set` will be on the stack
rc |= compile_ast_node_index_set(ctx, vars->arr[i]->node);
continue;
}
41026c95a8750b90227ea3f5886f517f354e0215
比如使用string代替const char*,左值引用代替指针并更少地在程序中使用malloc/new/free/delete,从而删除一些不必要的实现并提升程序的可读性...原谅菜逼看不懂大佬的代码实现
find out why the line below do not work
hg_func.as.user_def = ctx->chk->code + ctx->chk->len;
Line 645 in 7cdec3d
int j_patch_pos = chunk_write_word(ctx->chk, 0u);
// TODO: find out why the line below do not work
// hg_func.as.user_def = ctx->chk->code + ctx->chk->len;
hg_func.as.user_def = ctx->chk->len;
int loc = chunk_add_func(ctx->chk, hg_func);
hash_map_put(&ctx->funcs, *id, VAL_INT(loc));
ndex cf6f30e..cff699d 100644
++ b/src/function.h
dfa202d33843901a9b822b2923796929c750da76
only find variable in the same scope
need some tests
Line 372 in 20f6c7b
}
static int compile_ast_node_args(struct compiler_context* ctx, void* _args) {
struct ast_node_array* args = _args;
int rc = 0;
for (size_t i = 0; i < args->len; i++) {
// push inversely
rc |= compile_ast_node(ctx, args->arr[i]);
}
return rc;
}
static int compile_define_vars(struct compiler_context* ctx, void* _vars) {
struct ast_node_array* vars = _vars;
int rc = 0;
for (size_t i = 0; i < vars->len; i++) {
struct hg_value* id = vars->arr[i]->node;
int loc;
bool islocal;
// TODO: only find variable in the same scope
// need some tests
if ((loc = find_variable(ctx, *id, &islocal)) != -1) {
fprintf(stderr, "redefine variable: ");
hg_value_write(*id, stderr, true);
fprintf(stderr, "\n");
return -1;
} else if (ctx->scope_depth == 0) {
// define global var
loc = chunk_add_static(ctx->chk, VAL_UNDEF());
hash_map_put(&ctx->global_vars, *id, VAL_INT(loc));
chunk_write(ctx->chk, OP_SET_STATIC);
chunk_write_word(ctx->chk, loc);
} else {
// define local var
add_local(ctx, ((struct hg_string*)VAL_AS_OBJ(*id))->str);
}
}
return rc;
}
static int compile_set_vars(struct compiler_context* ctx, void* _vars) {
struct ast_node_array* vars = _vars;
int rc = 0;
for (int i = vars->len - 1; i >= 0; i--) {
struct hg_value* id = vars->arr[i]->node;
int loc;
bool islocal;
if ((loc = find_variable(ctx, *id, &islocal)) != -1) {
chunk_write(ctx->chk, islocal ? OP_SET_LOCAL : OP_SET_STATIC);
chunk_write_word(ctx->chk, loc);
} else {
fprintf(stderr, "compile error: reference before definition: ");
hg_value_write(*id, stderr, true);
fprintf(stderr, "\n");
rc |= -1;
}
}
return rc;
}
static int compile_ast_node_assign(struct compiler_context* ctx,
void* _assign) {
struct ast_node_assign* node = _assign;
// check if args.len == vars.len
struct ast_node_array* args = node->args->node;
struct ast_node_array* vars = node->vars->node;
int rc = 0;
if (args->len != vars->len) {
fprintf(stderr,
"compiler error: expect %ld on the left of assignment but got "
"%ld\n",
vars->len, args->len);
return -1;
}
rc |= compile_ast_node(ctx, node->args);
rc |= compile_set_vars(ctx, node->vars->node);
return rc;
}
static int compile_ast_node_let(struct compiler_context* ctx, void* _assign) {
struct ast_node_assign* node = _assign;
// check if args.len == vars.len
struct ast_node_array* args = node->args->node;
struct ast_node_array* vars = node->vars->node;
if (args->len != vars->len) {
fprintf(stderr,
"compiler error: expect %ld on the left of assignment but got "
"%ld\n",
vars->len, args->len);
return -1;
}
int rc = 0;
rc |= compile_ast_node(ctx, node->args);
rc |= compile_define_vars(ctx, node->vars->node);
return rc;
}
/* IF-ELSE-IF-ELSE:
8d88864f154f0ae376ed79fdfbf21889d18f0184
free referrence to str
Line 423 in ac62e6b
}
void hg_ast_node_free(struct hg_ast_node* _node) {
if (_node == NULL)
return;
switch (_node->type) {
case AST_NODE_ASSIGNMENT: {
_raw_to(_node, struct hg_ast_assignment_stat, node);
hg_ast_node_free(node->exprs);
hg_ast_node_free(node->vars);
hg_free(node);
} break;
case AST_NODE_FOR: {
_raw_to(_node, struct hg_ast_for_stat, node);
hg_ast_node_free(node->params);
hg_ast_node_free(node->iterator);
hg_ast_node_free(node->block);
hg_free(node);
} break;
case AST_NODE_IF: {
_raw_to(_node, struct hg_ast_if_stat, node);
hg_ast_node_free(node->condition);
hg_ast_node_free(node->block);
hg_ast_node_free(node->else_block);
hg_free(node);
} break;
case AST_NODE_FUNC: {
_raw_to(_node, struct hg_ast_func_stat, node);
hg_ast_node_free(node->id);
hg_ast_node_free(node->params);
hg_ast_node_free(node->block);
hg_free(node);
} break;
case AST_NODE_BREAK: {
_raw_to(_node, struct hg_ast_break_stat, node);
hg_free(node);
} break;
case AST_NODE_CONTINUE: {
_raw_to(_node, struct hg_ast_continue_stat, node);
hg_free(node);
} break;
case AST_NODE_RETURN: {
_raw_to(_node, struct hg_ast_return_stat, node);
hg_ast_node_free(node->exprs);
hg_free(node);
} break;
case AST_NODE_CALL: {
_raw_to(_node, struct hg_ast_call_expr, node);
hg_ast_node_free(node->callable);
hg_ast_node_free(node->args);
hg_free(node);
} break;
case AST_NODE_FIELD: {
_raw_to(_node, struct hg_ast_field_expr, node);
hg_ast_node_free(node->prefix);
hg_ast_node_free(node->field);
hg_free(node);
} break;
case AST_NODE_INDEX: {
_raw_to(_node, struct hg_ast_index_expr, node);
hg_ast_node_free(node->prefix);
hg_ast_node_free(node->index);
hg_free(node);
} break;
case AST_NODE_FUNC_DEF: {
_raw_to(_node, struct hg_ast_func_def_expr, node);
hg_ast_node_free(node->params);
hg_ast_node_free(node->block);
hg_free(node);
} break;
case AST_NODE_BINARY_EXPR: {
_raw_to(_node, struct hg_ast_binary_expr, node);
hg_ast_node_free(node->left);
hg_ast_node_free(node->right);
hg_free(node);
} break;
case AST_NODE_UNARY_EXPR: {
_raw_to(_node, struct hg_ast_unary_expr, node);
hg_ast_node_free(node->expr);
hg_free(node);
} break;
case AST_NODE_TABLE: {
_raw_to(_node, struct hg_ast_table_expr, node);
hg_ast_node_free(node->entries);
hg_free(node);
} break;
case AST_NODE_TABLE_ENTRY: {
_raw_to(_node, struct hg_ast_table_entry, node);
hg_ast_node_free(node->key);
hg_ast_node_free(node->value);
hg_free(node);
} break;
case AST_NODE_LITERAL_STR: {
_raw_to(_node, struct hg_ast_literal, node);
// TODO: free referrence to str
hg_free(node);
} break;
case AST_NODE_LITERAL_ID: {
_raw_to(_node, struct hg_ast_literal, node);
// TODO: free referrence to str
hg_free(node);
} break;
case AST_NODE_LITERAL_BOOL: {
_raw_to(_node, struct hg_ast_literal, node);
hg_free(node);
} break;
case AST_NODE_LITERAL_INT: {
_raw_to(_node, struct hg_ast_literal, node);
hg_free(node);
} break;
case AST_NODE_LITERAL_FLOAT: {
_raw_to(_node, struct hg_ast_literal, node);
hg_free(node);
} break;
case AST_NODE_ARRAY: {
_raw_to(_node, struct hg_ast_node_array, node);
for (int i = 0; i < node->len; i++) {
hg_free(node->arr[i]);
}
hg_free(node);
} break;
default:
unreachable_();
}
}
static void _node_to_str(struct hg_ast_node* node, uint32_t indent,
struct hg_string_buffer* buffer) {
}
hg_char hg_ast_node_to_str(struct hg_ast_node* node, uint32_t indent) {
}
#undef _new
#undef _raw
#undef _raw_to
ndex 8066773..5c493a5 100644
++ b/src/ast.h
fa97fe5059e2d4d46f6ce5777e1f001e01eda2d2
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.