@@ -289,6 +289,7 @@ Script interpreter. Works the same as ic3 but is not interactive.
## TODO
- libc3
+ - height function `(TAG_VOID: 0, TAG_TUPLE: max(height(tuple->tags)))`
- macros
- modules
- defmodule
@@ -298,8 +299,8 @@ Script interpreter. Works the same as ic3 but is not interactive.
- with ignore variables
- math
- ratios
- - floating point numbers (decimals)
- - floating point numbers (ieee854)
+ - arbitrary precision floating point numbers (decimals)
+ - floating point numbers (ieee754)
- maps
- get (get key value)
- put (return a new map)
new file mode 100644
@@ -0,0 +1,144 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include "assert.h"
+#include <stdlib.h>
+#include <string.h>
+#include "buf.h"
+#include "buf_inspect.h"
+#include "buf_parse.h"
+#include "io.h"
+#include "block.h"
+#include "tag.h"
+
+void block_clean (s_block *block)
+{
+ tuple_clean(&block->tuple);
+}
+
+void block_delete (s_block *block)
+{
+ block_clean(block);
+ free(block);
+}
+
+s_block * block_init (s_block *block, uw count)
+{
+ s_block tmp = {0};
+ if (! tuple_init(&tmp->tuple, count))
+ return NULL;
+ *block = tmp;
+ return block;
+}
+
+s_block * block_init_1 (s_block *block, const char *p)
+{
+ s_buf buf;
+ uw len;
+ sw r;
+ assert(block);
+ assert(p);
+ len = strlen(p);
+ buf_init(&buf, false, len, (char *) p);
+ buf.wpos = len;
+ r = buf_parse_block(&buf, block);
+ if (r < 0 || (uw) r != len) {
+ err_write_1("block_init_1: invalid block: \"");
+ err_write_1(p);
+ err_write_1("\", ");
+ err_inspect_uw(&len);
+ err_write_1(" != ");
+ err_inspect_sw(&r);
+ err_write_1("\n");
+ assert(! "block_init_1: invalid block");
+ return NULL;
+ }
+ return block;
+}
+
+s_block * block_init_cast (s_block *block, const s_tag *tag)
+{
+ switch (tag->type) {
+ case TAG_BLOCK:
+ return block_init_copy(block, &tag->data.block);
+ default:
+ break;
+ }
+ err_write_1("block_init_cast: cannot cast ");
+ err_write_1(tag_type_to_string(tag->type));
+ err_puts(" to Block");
+ assert(! "block_init_cast: cannot cast to Block");
+ return NULL;
+}
+
+s_block * block_init_copy (s_block *block, const s_block *src)
+{
+ uw i = 0;
+ assert(src);
+ assert(block);
+ block_init(block, src->count);
+ while (i < src->count) {
+ tag_init_copy(block->tag + i, src->tag + i);
+ i++;
+ }
+ return block;
+}
+
+s_str * block_inspect (const s_block *x, s_str *dest)
+{
+ s_buf buf;
+ sw r;
+ sw size;
+ size = buf_inspect_block_size(x);
+ buf_init_alloc(&buf, size);
+ if ((r = buf_inspect_block(&buf, x)) < 0)
+ goto error;
+ assert(r == size);
+ if (r != size)
+ goto error;
+ return buf_to_str(&buf, dest);
+ error:
+ buf_clean(&buf);
+ return NULL;
+}
+
+s_block * block_new (uw count)
+{
+ s_block *block;
+ block = malloc(sizeof(s_block));
+ if (! block) {
+ err_puts("block_new: failed to allocate memory");
+ assert(! "block_new: failed to allocate memory");
+ return NULL;
+ }
+ if (! block_init(block, count)) {
+ free(block);
+ return NULL;
+ }
+ return block;
+}
+
+s_block * block_new_1 (const char *p)
+{
+ s_block *block;
+ block = malloc(sizeof(s_block));
+ if (! block) {
+ err_puts("block_new_1: failed to allocate memory");
+ assert(! "block_new_1: failed to allocate memory");
+ return NULL;
+ }
+ if (! block_init_1(block, p)) {
+ free(block);
+ return NULL;
+ }
+ return block;
+}
new file mode 100644
@@ -0,0 +1,46 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/**
+ * @file block.h
+ * @brief A block of code (a tuple of tags).
+ *
+ * A block is a tuple of tags representing code.
+ */
+#ifndef LIBC3_BLOCK_H
+#define LIBC3_BLOCK_H
+
+#include "hash.h"
+#include "types.h"
+
+/* Stack allocation compatible functions */
+s_block * block_init (s_block *block, uw count);
+s_block * block_init_1 (s_block *block, const char *p);
+s_block * block_init_cast (s_block *block, const s_tag *tag);
+s_block * block_init_copy (s_block *block, const s_block *src);
+void block_clean (s_block *block);
+
+/* Constructors, call block_delete after use */
+s_block * block_new (uw count);
+s_block * block_new_1 (const char *p);
+
+/* Destructor */
+void block_delete (s_block *block);
+
+/* Modifiers */
+s_block * block_1 (s_block *block, const char *p);
+
+/* Observers */
+s_list * block_to_list (const s_block *block, s_list **list);
+s_str * block_inspect (const s_block *x, s_str *dest);
+
+#endif /* LIBC3_BLOCK_H */
@@ -23,22 +23,46 @@ bool * bool_init_cast (bool *b, const s_tag *tag)
assert(b);
assert(tag);
switch (tag->type) {
- case TAG_BOOL: *b = tag->data.bool; return b;
- case TAG_CHARACTER: *b = (bool) tag->data.character; return b;
- case TAG_F32: *b = (bool) tag->data.f32; return b;
- case TAG_F64: *b = (bool) tag->data.f64; return b;
- case TAG_INTEGER: *b = integer_to_u8(&tag->data.integer); return b;
- case TAG_S8: *b = (bool) tag->data.s8; return b;
- case TAG_S16: *b = (bool) tag->data.s16; return b;
- case TAG_S32: *b = (bool) tag->data.s32; return b;
- case TAG_S64: *b = (bool) tag->data.s64; return b;
- case TAG_SW: *b = (bool) tag->data.sw; return b;
- case TAG_U8: *b = (bool) tag->data.u8; return b;
- case TAG_U16: *b = (bool) tag->data.u16; return b;
- case TAG_U32: *b = (bool) tag->data.u32; return b;
- case TAG_U64: *b = (bool) tag->data.u64; return b;
- case TAG_UW: *b = (bool) tag->data.uw; return b;
- default: break;
+ case TAG_BOOL: *b = tag->data.bool; return b;
+ case TAG_CHARACTER: *b = (bool) tag->data.character; return b;
+ case TAG_F32: *b = (bool) tag->data.f32; return b;
+ case TAG_F64: *b = (bool) tag->data.f64; return b;
+ case TAG_F128: *b = (bool) tag->data.f128; return b;
+ case TAG_INTEGER:
+ *b = ! integer_is_zero(&tag->data.integer); return b;
+ case TAG_S8: *b = tag->data.s8 != 0; return b;
+ case TAG_S16: *b = tag->data.s16 != 0; return b;
+ case TAG_S32: *b = tag->data.s32 != 0; return b;
+ case TAG_S64: *b = tag->data.s64 != 0; return b;
+ case TAG_SW: *b = tag->data.sw != 0; return b;
+ case TAG_U8: *b = tag->data.u8 != 0; return b;
+ case TAG_U16: *b = tag->data.u16 != 0; return b;
+ case TAG_U32: *b = tag->data.u32 != 0; return b;
+ case TAG_U64: *b = tag->data.u64 != 0; return b;
+ case TAG_UW: *b = tag->data.uw != 0; return b;
+ case TAG_PTAG: return tag->data.ptag ?
+ bool_init_cast(b, tag->data.ptag) : (*b = false, b);
+ case TAG_PTR: *b = tag->data.ptr.p != 0; return b;
+ case TAG_PTR_FREE: *b = tag->data.ptr_free.p != 0; return b;
+ case TAG_ARRAY:
+ case TAG_BLOCK:
+ case TAG_CALL:
+ case TAG_CFN:
+ case TAG_FACT:
+ case TAG_FN:
+ case TAG_IDENT:
+ case TAG_LIST:
+ case TAG_MAP:
+ case TAG_QUOTE:
+ case TAG_STR:
+ case TAG_STRUCT:
+ case TAG_STRUCT_TYPE:
+ case TAG_SYM:
+ case TAG_TUPLE:
+ case TAG_UNQUOTE:
+ case TAG_VAR:
+ case TAG_VOID:
+ break;
}
err_write_1("bool_cast: cannot cast ");
err_write_1(tag_type_to_string(tag->type));
@@ -2122,6 +2122,7 @@ sw buf_inspect_tag (s_buf *buf, const s_tag *tag)
return buf_write_1(buf, "NULL");
switch(tag->type) {
case TAG_ARRAY: return buf_inspect_array(buf, &tag->data.array);
+ case TAG_BLOCK: return buf_inspect_block(buf, &tag->data.block);
case TAG_BOOL: return buf_inspect_bool(buf, &tag->data.bool);
case TAG_CALL: return buf_inspect_call(buf, &tag->data.call);
case TAG_CFN: return buf_inspect_cfn(buf, &tag->data.cfn);
@@ -2172,6 +2173,7 @@ sw buf_inspect_tag_size (const s_tag *tag)
assert(tag);
switch(tag->type) {
case TAG_ARRAY: return buf_inspect_array_size(&tag->data.array);
+ case TAG_BLOCK: return buf_inspect_block_size(&tag->data.block);
case TAG_BOOL: return buf_inspect_bool_size(&tag->data.bool);
case TAG_CALL: return buf_inspect_call_size(&tag->data.call);
case TAG_CFN: return buf_inspect_cfn_size(&tag->data.cfn);
@@ -55,6 +55,8 @@
sw buf_inspect_array (s_buf *buf, const s_array *a);
sw buf_inspect_array_size (const s_array *a);
+sw buf_inspect_block (s_buf *buf, const s_block *b);
+sw buf_inspect_block_size (const s_block *b);
sw buf_inspect_bool (s_buf *buf, const bool *b);
sw buf_inspect_bool_size (const bool *b);
sw buf_inspect_call (s_buf *buf, const s_call *call);
@@ -864,6 +864,8 @@ s8 compare_tag (const s_tag *a, const s_tag *b) {
case TAG_VOID: return 0;
case TAG_ARRAY: return compare_array(&a->data.array,
&b->data.array);
+ case TAG_BLOCK: return compare_block(&a->data.block,
+ &b->data.block);
case TAG_BOOL: return compare_bool(a->data.bool, b->data.bool);
case TAG_CALL: return compare_call(&a->data.call,
&b->data.call);
@@ -19,6 +19,7 @@
s8 compare_##type (type a, type b)
s8 compare_array (const s_array *a, const s_array *b);
+s8 compare_block (const s_block *a, const s_block *b);
s8 compare_bool (bool a, bool b);
s8 compare_call (const s_call *a, const s_call *b);
s8 compare_cfn (const s_cfn *a, const s_cfn *b);
@@ -358,6 +358,7 @@ bool env_eval_equal_map (s_env *env, const s_map *a,
return true;
}
+// TODO: pin operator
bool env_eval_equal_tag (s_env *env, const s_tag *a, const s_tag *b,
s_tag *dest)
{
@@ -455,6 +456,10 @@ bool env_eval_equal_tag (s_env *env, const s_tag *a, const s_tag *b,
dest->type = TAG_TUPLE;
return env_eval_equal_tuple(env, &a->data.tuple, &b->data.tuple,
&dest->data.tuple);
+ case TAG_BLOCK:
+ dest->type = TAG_BLOCK;
+ return env_eval_equal_block(env, &a->data.block, &b->data.block,
+ &dest->data.block);
case TAG_CALL:
case TAG_QUOTE:
case TAG_ARRAY:
@@ -849,6 +854,8 @@ bool env_eval_quote_tag (s_env *env, const s_tag *tag, s_tag *dest)
switch (tag->type) {
case TAG_ARRAY:
return env_eval_quote_array(env, &tag->data.array, dest);
+ case TAG_BLOCK:
+ return env_eval_quote_block(env, &tag->data.block, dest);
case TAG_CALL:
return env_eval_quote_call(env, &tag->data.call, dest);
case TAG_LIST:
@@ -1036,6 +1043,8 @@ bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
return env_eval_void(env, NULL, dest);
case TAG_ARRAY:
return env_eval_array_tag(env, &tag->data.array, dest);
+ case TAG_BLOCK:
+ return env_eval_block(env, &tag->data.block, dest);
case TAG_CALL:
return env_eval_call(env, &tag->data.call, dest);
case TAG_IDENT:
@@ -26,6 +26,8 @@ bool env_eval_array (s_env *env, const s_array *array,
s_array *dest);
bool env_eval_array_tag (s_env *env, const s_array *array,
s_tag *dest);
+bool env_eval_block (s_env *env, const s_block *block,
+ s_tag *dest);
bool env_eval_call (s_env *env, const s_call *call,
s_tag *dest);
bool env_eval_call_arguments (s_env *env, const s_list *args,
@@ -35,6 +37,8 @@ bool env_eval_call_cfn (s_env *env, const s_call *call,
bool env_eval_call_fn (s_env *env, const s_call *call,
s_tag *dest);
bool env_eval_call_resolve (s_env *env, s_call *call);
+bool env_eval_equal_block (s_env *env, const s_block *a,
+ const s_block *b, s_block *dest);
bool env_eval_equal_list (s_env *env, const s_list *a,
const s_list *b, s_list **dest);
bool env_eval_equal_struct (s_env *env, const s_struct *a,
@@ -59,6 +63,8 @@ bool env_eval_quote (s_env *env, const s_quote *quote,
s_tag *dest);
bool env_eval_quote_array (s_env *env, const s_array *array,
s_tag *dest);
+bool env_eval_quote_block (s_env *env, const s_block *block,
+ s_tag *dest);
bool env_eval_quote_call (s_env *env, const s_call *call,
s_tag *dest);
bool env_eval_quote_list (s_env *env, const s_list *list,
@@ -419,6 +419,7 @@ bool hash_update_tag (t_hash *hash, const s_tag *tag)
return false;
switch (tag->type) {
case TAG_ARRAY: return hash_update_array(hash, &tag->data.array);
+ case TAG_BLOCK: return hash_update_block(hash, &tag->data.block);
case TAG_BOOL: return hash_update_bool(hash, &tag->data.bool);
case TAG_CALL: return hash_update_call(hash, &tag->data.call);
case TAG_CFN: return hash_update_cfn(hash, &tag->data.cfn);
@@ -25,6 +25,7 @@ u64 hash_to_u64 (t_hash *hash);
bool hash_update (t_hash *hash, const void *data, uw size);
bool hash_update_1 (t_hash *hash, const char *p);
bool hash_update_array (t_hash *hash, const s_array *a);
+bool hash_update_block (t_hash *hash, const s_block *block);
bool hash_update_bool (t_hash *hash, const bool *b);
bool hash_update_call (t_hash *hash, const s_call *call);
bool hash_update_cfn (t_hash *hash, const s_cfn *cfn);
@@ -18,6 +18,7 @@ const s_sym g_sym__brackets = {{{NULL}, 2, {"[]"}}};
const s_sym g_sym__paren = {{{NULL}, 2, {"()"}}};
const s_sym g_sym__plus = {{{NULL}, 1, {"+"}}};
const s_sym g_sym_Array = {{{NULL}, 5, {"Array"}}};
+const s_sym g_sym_Block = {{{NULL}, 5, {"Block"}}};
const s_sym g_sym_Bool = {{{NULL}, 4, {"Bool"}}};
const s_sym g_sym_C3 = {{{NULL}, 2, {"C3"}}};
const s_sym g_sym_Call = {{{NULL}, 4, {"Call"}}};
@@ -251,6 +252,7 @@ void sym_init_g_sym (void)
sym_intern(&g_sym__paren, NULL);
sym_intern(&g_sym__plus, NULL);
sym_intern(&g_sym_Array, NULL);
+ sym_intern(&g_sym_Block, NULL);
sym_intern(&g_sym_Bool, NULL);
sym_intern(&g_sym_C3, NULL);
sym_intern(&g_sym_Call, NULL);
@@ -30,6 +30,7 @@ extern const s_sym g_sym__brackets;
extern const s_sym g_sym__paren;
extern const s_sym g_sym__plus;
extern const s_sym g_sym_Array;
+extern const s_sym g_sym_Block;
extern const s_sym g_sym_Bool;
extern const s_sym g_sym_C3;
extern const s_sym g_sym_Call;
@@ -17,6 +17,7 @@
#include <string.h>
#include <strings.h>
#include "array.h"
+#include "block.h"
#include "buf.h"
#include "buf_inspect.h"
#include "buf_parse.h"
@@ -178,6 +179,7 @@ void tag_clean (s_tag *tag)
assert(tag);
switch (tag->type) {
case TAG_ARRAY: array_clean(&tag->data.array); break;
+ case TAG_BLOCK: block_clean(&tag->data.block); break;
case TAG_CALL: call_clean(&tag->data.call); break;
case TAG_CFN: cfn_clean(&tag->data.cfn); break;
case TAG_FN: fn_clean(&tag->data.fn); break;
@@ -354,6 +356,9 @@ s_tag * tag_init_copy (s_tag *tag, const s_tag *src)
case TAG_ARRAY:
array_init_copy(&tag->data.array, &src->data.array);
break;
+ case TAG_BLOCK:
+ block_init_copy(&tag->data.block, &src->data.block);
+ break;
case TAG_CALL:
call_init_copy(&tag->data.call, &src->data.call);
break;
@@ -540,7 +545,7 @@ s_tag * tag_neg (const s_tag *tag, s_tag *result)
s_integer tmp;
switch (tag->type) {
case TAG_BOOL:
- return tag_init_s8(result, -(tag->data.bool ? 1 : 0));
+ return tag_init_s8(result, tag->data.bool ? -1 : 0);
case TAG_CHARACTER:
return tag_init_s64(result, -tag->data.character);
case TAG_INTEGER:
@@ -682,6 +687,7 @@ bool tag_to_const_pointer (const s_tag *tag, const s_sym *type,
}
switch (tag_type) {
case TAG_ARRAY: *dest = &tag->data.array; return true;
+ case TAG_BLOCK: *dest = &tag->data.block; return true;
case TAG_BOOL: *dest = &tag->data.bool; return true;
case TAG_CALL: *dest = &tag->data.call; return true;
case TAG_CFN: *dest = &tag->data.cfn; return true;
@@ -743,6 +749,12 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
return true;
}
goto invalid_cast;
+ case TAG_BLOCK:
+ if (type == &g_sym_Block) {
+ *dest = &tag->data.block;
+ return true;
+ }
+ goto invalid_cast;
case TAG_BOOL:
if (type == &g_sym_Bool) {
*dest = &tag->data.bool;
@@ -986,6 +998,7 @@ bool tag_to_pointer (s_tag *tag, const s_sym *type, void **dest)
switch (tag_type) {
case TAG_VOID: *dest = NULL; return true;
case TAG_ARRAY: *dest = &tag->data.array; return true;
+ case TAG_BLOCK: *dest = &tag->data.block; return true;
case TAG_BOOL: *dest = &tag->data.bool; return true;
case TAG_CALL: *dest = &tag->data.call; return true;
case TAG_CFN: *dest = &tag->data.cfn; return true;
@@ -1035,6 +1048,7 @@ const s_sym ** tag_type (const s_tag *tag, const s_sym **dest)
case TAG_ARRAY:
*dest = tag->data.array.array_type;
return dest;
+ case TAG_BLOCK: *dest = &g_sym_Block; return dest;
case TAG_BOOL: *dest = &g_sym_Bool; return dest;
case TAG_CALL: *dest = &g_sym_Call; return dest;
case TAG_CFN: *dest = &g_sym_Cfn; return dest;
@@ -18,6 +18,7 @@ bool tag_type_size (e_tag_type type, uw *dest)
switch (type) {
case TAG_VOID: *dest = 0; return true;
case TAG_ARRAY: *dest = sizeof(s_array); return true;
+ case TAG_BLOCK: *dest = sizeof(s_block); return true;
case TAG_BOOL: *dest = sizeof(bool); return true;
case TAG_CALL: *dest = sizeof(s_call); return true;
case TAG_CFN: *dest = sizeof(s_cfn); return true;
@@ -62,6 +63,7 @@ bool tag_type_to_ffi_type (e_tag_type type, ffi_type **dest)
{
switch (type) {
case TAG_ARRAY: *dest = &ffi_type_pointer; return true;
+ case TAG_BLOCK: *dest = &ffi_type_pointer; return true;
case TAG_BOOL: *dest = &ffi_type_uint8; return true;
case TAG_CALL: *dest = &ffi_type_pointer; return true;
case TAG_CFN: *dest = &ffi_type_pointer; return true;
@@ -108,6 +110,7 @@ const char * tag_type_to_string (e_tag_type tag_type)
switch (tag_type) {
case TAG_VOID: return "Void";
case TAG_ARRAY: return "Array";
+ case TAG_BLOCK: return "Block";
case TAG_BOOL: return "Bool";
case TAG_CALL: return "Call";
case TAG_CFN: return "Cfn";
@@ -41,9 +41,7 @@ void tuple_delete (s_tuple *tuple);
s_tuple * tuple_1 (s_tuple *tuple, const char *p);
/* Observers */
-s_list * tuple_to_list (const s_tuple *tuple, s_list **list);
-
-/* Call str_delete after use. */
-s_str * tuple_inspect (const s_tuple *x, s_str *dest);
+s_list * tuple_to_list (const s_tuple *tuple, s_list **list);
+s_str * tuple_inspect (const s_tuple *x, s_str *dest);
#endif /* LIBC3_TUPLE_H */
@@ -91,6 +91,7 @@ typedef enum {
typedef enum {
TAG_VOID = 0,
TAG_ARRAY,
+ TAG_BLOCK,
TAG_BOOL,
TAG_CALL,
TAG_CFN,
@@ -132,6 +133,7 @@ typedef struct arg s_arg;
typedef struct array s_array;
typedef struct array_dimension s_array_dimension;
typedef struct binding s_binding;
+typedef struct block s_block;
typedef struct buf s_buf;
typedef struct buf_save s_buf_save;
typedef struct call s_call;
@@ -196,6 +198,7 @@ typedef bool (* f_sequence_button) (s_sequence *seq, u8 button, sw x,
#define SKIPLIST_HEIGHT_MAX U64_MAX
/* 1 */
+
struct array_dimension {
uw count;
uw item_size;
@@ -296,6 +299,11 @@ struct unwind_protect {
};
/* 2 */
+
+struct block {
+ s_tuple tuple;
+};
+
struct buf {
sw column;
sw (*flush) (s_buf *buf);
@@ -348,6 +356,7 @@ struct struct_type {
};
/* 3 */
+
struct call {
/* key */
s_ident ident;
@@ -393,6 +402,7 @@ struct type {
};
/* 4 */
+
struct array {
uw count;
uw dimension;
@@ -406,8 +416,10 @@ struct array {
};
/* 5 */
+
union tag_data {
s_array array;
+ s_block block;
bool bool;
s_call call;
s_cfn cfn;
@@ -444,12 +456,14 @@ union tag_data {
};
/* 6 */
+
struct tag {
e_tag_type type;
u_tag_data data;
};
/* 7 */
+
struct arg {
const s_sym *name;
s_type type;
@@ -544,6 +558,7 @@ TYPEDEF_SKIPLIST_NODE(fact, s_fact *);
TYPEDEF_SKIPLIST(fact, s_fact *);
/* 8 */
+
struct facts {
s_set__tag tags;
s_set__fact facts;
@@ -570,6 +585,7 @@ struct facts_cursor {
};
/* 9 */
+
struct env {
sw argc;
char **argv;
@@ -596,6 +612,7 @@ struct facts_with_cursor_level {
};
/* 10 */
+
struct facts_with_cursor {
s_facts *facts;
s_binding *bindings;
@@ -30,8 +30,7 @@ static const char * g_gl_camera_vertex_shader_src =
"void main() {\n"
" gl_Position = vec4(uProjectionMatrix * uViewMatrix *\n"
" uModelMatrix * vec4(iPos, 1.0));\n"
- " ioNormal = vec3(mat3(transpose(inverse(uModelMatrix))) *\n"
- " iNormal);\n"
+ " ioNormal = vec3(uViewMatrix * uModelMatrix * vec4(iNormal, 1.0));\n"
" ioPos = (uViewMatrix * uModelMatrix * vec4(iPos, 1.0)).xyz;\n"
" ioTexCoord = iTexCoord;\n"
"}\n";
@@ -274,7 +273,6 @@ void gl_camera_render (s_gl_camera *camera)
&(s_vec3) { 0.0f, 0.0f, 1.0f });
mat4_init_identity(&camera->model_matrix);
mat4_init_copy(&matrix, &camera->view_matrix);
- mat4_mult_mat4(&camera->projection_matrix, &matrix, &matrix);
for (int i = 0; i < camera->light_count; i++)
mat4_mult_vec3(&matrix, camera->light_pos + i,
camera->light_pos_cam + i);