Skip to content

Commit

Permalink
Merge branch 'main' into ee7/add-initial-test-workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
ee7 committed Jun 20, 2024
2 parents 3c09320 + 8333004 commit d575590
Show file tree
Hide file tree
Showing 39 changed files with 1,073 additions and 946 deletions.
19 changes: 12 additions & 7 deletions doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -537,36 +537,41 @@ EOS ::= '\n' | ';' <<or, if followed by a '}' or line comment, then ''>>
- __repr__

# Features to re-add from old con4m
- FFI
- VM save restore
- Arg parsing
- Libraries
- Actually collect garbage.
- Doc API.
- Folding
- Casting
- Checkpointing
- Hot loading
- Finish data types (date, ip, and extra hatrack stuff)
- Test harness
- Final mile: specs
- Final mile: params
- Auto-import standard library.
- Callbacks
- Tuple unpacking
- Len, etc.

# Items for afterward
- Objects
- Folding
- Casting
- Varargs functions
- Clean up unused instructions in VM
- Remove the two-words-per-stack-slot thing; it's not needed anymore.
- Test harness
- Objects
- automatic logfd + optional server for log messages
- REPL
- Keyword arguments
- 'maybe' types / nil
- Aspects
- Aspects (before / after / around pattern(sig) when x)
- Casting
- (Possibly) re-add := literals
- Threading
- Mixed
- Pretty printing w/ type annotations
- Language server
- Checks based on PDG
- Full-program info on unused fields & fns.

# Features removed (considered for adding back in)
Also, the language accepts ":=", which has the special syntax of
Expand Down
7 changes: 5 additions & 2 deletions include/compiler/errors.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#pragma once
#include "con4m.h"

extern c4m_str_t *c4m_format_error_message(c4m_compile_error *, bool);
extern c4m_grid_t *c4m_format_errors(c4m_compile_ctx *);
extern c4m_str_t *c4m_format_error_message(c4m_compile_error *, bool);
extern c4m_grid_t *c4m_format_errors(c4m_compile_ctx *);
extern c4m_xlist_t *c4m_compile_extract_all_error_codes(c4m_compile_ctx *);
extern c4m_utf8_t *c4m_err_code_to_str(c4m_compile_error_t);

extern c4m_compile_error *c4m_base_add_error(c4m_xlist_t *,
c4m_compile_error_t,
c4m_token_t *,
Expand Down
1 change: 1 addition & 0 deletions include/con4m/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <netdb.h>
#include <dlfcn.h>
#include <pwd.h>
#include <dirent.h>

#include <sys/select.h>
#include <sys/types.h>
Expand Down
27 changes: 8 additions & 19 deletions include/con4m/datatypes/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,6 @@ typedef enum : uint8_t {
// value. The type of the immediate value is encoded in the instruction's
// type_info.
C4M_ZPushImm = 0x07,
// Push the type of a value onto the stack. The value to operate on is
// determined as described in the above comment about address encodings.
C4M_ZPushSType = 0x08,
// For an object on top of the stack, will retrieve and push the object's
// type. Note that the top of the stack must not be a raw value type;
// if it's not a by-reference type, box it first.
Expand Down Expand Up @@ -130,6 +127,8 @@ typedef enum : uint8_t {
// implementation (ffi function index), name offset, and type info,
// respectively. The ZRunCallback instruction is used to run the callback,
// which is run as an FFI function.
//
// Currently unused.
C4M_ZPushFfiPtr = 0x0E,
// Create a callback and push it onto the stack. The instruction's arg,
// immediate, and type_info fields are encoded into the callback as the
Expand All @@ -147,18 +146,14 @@ typedef enum : uint8_t {
// Pops the top value from the stack. This is the same as C4M_ZMoveSp with
// an adjustment of -1.
C4M_ZPop = 0x20,
// Stores the value at the top of the stack to the value address encoded in
// the instruction. The storage address is determined as described in the
// above comment about address encodings. The value assigned from the stack
// is not popped.
C4M_ZStoreTop = 0x21,
// Stores the encoded immediate value into the value address encoded in the
// instruction. The storage address is determined as described in the above
// comment about address encodings.
C4M_ZStoreImm = 0x22,
// Unpack the elements of a tuple, storing each one into the lvalue on the
// stack, popping each lvalue as its assigned. The number of assignments to
// perform is encoded in the instruction's arg field.
// currently unused.
C4M_ZUnpack = 0x23,
// Swap the two top values on the stack.
C4M_ZSwap = 0x24,
Expand Down Expand Up @@ -215,11 +210,7 @@ typedef enum : uint8_t {
// from the callback. Otherwise, the callback is the same as a native call
// via C4M_Z0Call, except it uses the index from the callback.
C4M_ZRunCallback = 0x37,
// which currently always gets stored in 64 bits, and must be a value type.
// Unmarshals the data stored in the static data area beginning at the
// offset encoded into the instruction's immediate field. The length of the
// marhsalled data is encoded in the instruction's arg field. The resulting
// object is pushed onto the stack.
// Unused; will redo when adding objects.
C4M_ZSObjNew = 0x38,
// Box a literal, which requires supplying the type for the object.
C4M_ZBox = 0x40,
Expand Down Expand Up @@ -279,12 +270,6 @@ typedef enum : uint8_t {
// Initialze module parameters. The number of parameters is encoded in the
// instruction's arg field. This is only used during module initialization.
C4M_ZModuleEnter = 0x83,
// Pops the top stack value and tests it. The value is expected to be either
// a string or NULL. If it is a string and is not an empty string, it will
// be used as an error message and evalutation will stop. This is basically
// a specialized assert used during module initialization to validate
// module parameters.
C4M_ZParamCheck = 0x84,
// Adjust the stack pointer down by the amount encoded in the instruction's
// arg field. This means specifically that the arg field is subtracted from
// sp, so a single pop would encode -1 as the adjustment.
Expand Down Expand Up @@ -537,6 +522,10 @@ typedef struct {
c4m_xlist_t *ffi_info;
int ffi_info_entries;
bool using_attrs;
#ifdef C4M_DEV
c4m_buf_t *print_buf;
c4m_stream_t *print_stream;
#endif
} c4m_vm_t;

typedef struct {
Expand Down
1 change: 1 addition & 0 deletions include/con4m/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ extern c4m_utf8_t *c4m_cstr_array_format(char *, int, c4m_utf8_t **);
_c4m_cstr_format(fmt, PP_NARG(__VA_ARGS__) __VA_OPT__(, ) __VA_ARGS__)
#define c4m_str_format(fmt, ...) \
_c4m_str_format(fmt, PP_NARG(__VA_ARGS__) __VA_OPT__(, ) __VA_ARGS__)
#define c4m_printf(fmt, ...) c4m_print(c4m_cstr_format(fmt, __VA_ARGS__))
27 changes: 22 additions & 5 deletions include/con4m/path.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
#pragma once
#include "con4m.h"

c4m_utf8_t *c4m_resolve_path(c4m_utf8_t *);
c4m_utf8_t *c4m_path_tilde_expand(c4m_utf8_t *);
c4m_utf8_t *c4m_get_user_dir(c4m_utf8_t *);
c4m_utf8_t *c4m_get_current_directory(c4m_utf8_t *);
c4m_utf8_t *c4m_path_join(c4m_xlist_t *);
typedef enum {
C4M_FK_NOT_FOUND = 0,
C4M_FK_IS_REG_FILE = S_IFREG,
C4M_FK_IS_DIR = S_IFDIR,
C4M_FK_IS_FLINK = S_IFLNK,
C4M_FK_IS_DLINK = S_IFLNK | S_IFDIR,
C4M_FK_IS_SOCK = S_IFSOCK,
C4M_FK_IS_CHR_DEVICE = S_IFCHR,
C4M_FK_IS_BLOCK_DEVICE = S_IFBLK,
C4M_FK_IS_FIFO = S_IFIFO,
C4M_FK_OTHER = ~0,
} c4m_file_kind;

c4m_utf8_t *c4m_resolve_path(c4m_utf8_t *);
c4m_utf8_t *c4m_path_tilde_expand(c4m_utf8_t *);
c4m_utf8_t *c4m_get_user_dir(c4m_utf8_t *);
c4m_utf8_t *c4m_get_current_directory(c4m_utf8_t *);
c4m_utf8_t *c4m_path_join(c4m_xlist_t *);
c4m_file_kind c4m_get_file_kind(c4m_utf8_t *);
c4m_xlist_t *_c4m_path_walk(c4m_utf8_t *, ...);

#define c4m_path_walk(x, ...) _c4m_path_walk(x, KFUNC(__VA_ARGS__))

static inline c4m_utf8_t *
c4m_get_home_directory()
Expand Down
12 changes: 12 additions & 0 deletions include/con4m/set.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,15 @@ c4m_set_disjunction(c4m_set_t *s1, c4m_set_t *s2)
hatrack_set_disjunction(s1, s2, result);
return result;
}

static inline c4m_dict_t *
c4m_dict(c4m_type_t *t1, c4m_type_t *t2)
{
return c4m_new(c4m_tspec_dict(t1, t2));
}

static inline c4m_set_t *
c4m_set(c4m_type_t *t)
{
return c4m_new(c4m_tspec_set(t));
}
2 changes: 2 additions & 0 deletions include/con4m/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ extern c4m_xlist_t *c4m_str_xsplit(c4m_str_t *, c4m_str_t *);
extern struct flexarray_t *c4m_str_split(c4m_str_t *, c4m_str_t *);
extern bool c4m_str_starts_with(const c4m_str_t *,
const c4m_str_t *);
extern bool c4m_str_ends_with(const c4m_str_t *,
const c4m_str_t *);
// This is in richlit.c
extern c4m_utf8_t *c4m_rich_lit(char *);

Expand Down
2 changes: 0 additions & 2 deletions include/con4m/switchboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,11 @@ extern void c4m_sb_init_party_input_buf(c4m_switchboard_t *,
char *,
size_t,
bool,
bool,
bool);
extern c4m_party_t *c4m_sb_new_party_input_buf(c4m_switchboard_t *,
char *,
size_t,
bool,
bool,
bool);
extern void c4m_sb_party_input_buf_new_string(c4m_party_t *,
char *,
Expand Down
2 changes: 1 addition & 1 deletion src/con4m/compiler/check_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -1900,7 +1900,7 @@ check_literal(pass2_ctx *ctx)
c4m_pnode_t *pnode = get_pnode(ctx->node);
c4m_str_t *litmod = pnode->extra_info;

if (litmod != NULL) {
if (litmod != NULL && litmod->data) {
litmod = c4m_to_utf8(litmod);
}

Expand Down
6 changes: 4 additions & 2 deletions src/con4m/compiler/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1671,6 +1671,7 @@ gen_sym_decl(gen_ctx *ctx)
int last = ctx->cur_node->num_kids - 1;
c4m_pnode_t *kid = get_pnode(ctx->cur_node->children[last]);
c4m_pnode_t *psym;
c4m_tree_node_t *cur = ctx->cur_node;
c4m_scope_entry_t *sym;

if (kid->kind == c4m_nt_assign) {
Expand All @@ -1682,8 +1683,9 @@ gen_sym_decl(gen_ctx *ctx)
return;
}

ctx->lvalue = true;
gen_one_kid(ctx, last);
ctx->cur_node = cur->children[last]->children[0];
gen_one_node(ctx);
ctx->cur_node = cur;
gen_sym_load(ctx, sym, true);
emit(ctx, C4M_ZAssignToLoc);
}
Expand Down
32 changes: 32 additions & 0 deletions src/con4m/compiler/errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,13 @@ static error_info_t error_info[] = {
},
};

c4m_utf8_t *
c4m_err_code_to_str(c4m_compile_error_t code)
{
error_info_t *info = (error_info_t *)&error_info[code];
return c4m_new_utf8(info->name);
}

c4m_utf8_t *
c4m_format_error_message(c4m_compile_error *one_err, bool add_code_name)
{
Expand Down Expand Up @@ -1265,6 +1272,31 @@ c4m_format_errors(c4m_compile_ctx *cctx)
return table;
}

c4m_xlist_t *
c4m_compile_extract_all_error_codes(c4m_compile_ctx *cctx)
{
c4m_xlist_t *result = c4m_xlist(c4m_tspec_ref());
uint64_t num_modules = 0;
hatrack_dict_item_t *view;

view = hatrack_dict_items_sort(cctx->module_cache, &num_modules);

for (unsigned int i = 0; i < num_modules; i++) {
c4m_file_compile_ctx *ctx = view[i].value;

if (ctx->errors != NULL) {
int n = c4m_xlist_len(ctx->errors);
for (int j = 0; j < n; j++) {
c4m_compile_error *err = c4m_xlist_get(ctx->errors, i, NULL);

c4m_xlist_append(result, (void *)(uint64_t)err->code);
}
}
}

return result;
}

c4m_compile_error *
c4m_base_add_error(c4m_xlist_t *err_list,
c4m_compile_error_t code,
Expand Down
2 changes: 1 addition & 1 deletion src/con4m/compiler/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1215,9 +1215,9 @@ extern_signature(parse_ctx *ctx)

if (tok_kind(ctx) == c4m_tt_rparen) {
consume(ctx);
end_node(ctx);
expect(ctx, c4m_tt_arrow);
extern_sig_item(ctx, c4m_nt_lit_tspec_return_type);
end_node(ctx);

return;
}
Expand Down
3 changes: 2 additions & 1 deletion src/con4m/hex.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@ add_offset(char **optr,
#define ASCIICHAR() \
if (*lineptr < 32 || *lineptr > 126) { \
*outptr++ = '.'; \
lineptr++; \
} \
else { \
*outptr++ = *lineptr; \
*outptr++ = *lineptr++; \
}

char *
Expand Down
8 changes: 8 additions & 0 deletions src/con4m/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,26 @@
char **c4m_stashed_argv;
char **c4m_stashed_envp;

// A few builtins here; will break this out soon.
uint64_t
c4m_clz(uint64_t n)
{
return __builtin_clzll(n);
}

uint64_t
c4m_rand()
{
return c4m_rand64();
}

static void
c4m_register_builtins()
{
c4m_add_static_function(c4m_new_utf8("c4m_clz"), c4m_clz);
c4m_add_static_function(c4m_new_utf8("c4m_gc_remove_hold"),
c4m_gc_remove_hold);
c4m_add_static_function(c4m_new_utf8("c4m_rand"), c4m_rand);
}

__attribute__((constructor)) void
Expand Down
Loading

0 comments on commit d575590

Please sign in to comment.