Skip to content

Commit

Permalink
Merge branch 'feature/nkl-core-cli-args-compiler-api' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
nk4rter committed Aug 3, 2024
2 parents fdda305 + c9602e7 commit caa5f3c
Show file tree
Hide file tree
Showing 46 changed files with 401 additions and 194 deletions.
4 changes: 3 additions & 1 deletion cmake/OutputTest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(OUTPUT_TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/output_test.sh")
function(def_output_test)
set(options)
set(oneValueArgs NAME FILE WORKING_DIRECTORY)
set(multiValueArgs COMMAND)
set(multiValueArgs COMMAND EXTRA_ARGS)

cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

Expand All @@ -27,13 +27,15 @@ function(def_output_test)
get_filename_component(TEST_FILE "${ARG_FILE}" ABSOLUTE)

string(JOIN " " CMD ${ARG_COMMAND})
string(JOIN " " ARGS ${ARG_EXTRA_ARGS})

make_directory("${ARG_WORKING_DIRECTORY}")
add_test(
NAME ${ARG_NAME}.${BASE_NAME}
COMMAND "${OUTPUT_TEST_SCRIPT}"
"--file=${TEST_FILE}"
"--cmd=${CMD}"
"--args=${ARGS}"
WORKING_DIRECTORY "${ARG_WORKING_DIRECTORY}"
)
endfunction()
8 changes: 6 additions & 2 deletions cmake/output_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ printUsage() {
echo "Options:"
echo " --file=<filepath> Path to the test file"
echo " --cmd=<command> Path to the tested executable"
echo " --args=<arguments> Extra arguments to forward"
echo " -h,--help Display this message"
}

Expand All @@ -22,6 +23,9 @@ while [ $# -gt 0 ]; do
--cmd=*)
ARG_CMD="${1#*=}"
;;
--args=*)
ARG_ARGS="${1#*=}"
;;
-h|--help)
printUsage
exit 0
Expand Down Expand Up @@ -83,7 +87,7 @@ printf "%s" "$EXPECTED_OUTPUT" > "$EXPECTED_STDOUT_FILE"
echo "Running command '$ARG_CMD $ARG_FILE'"

set +e
$ARG_CMD $ARG_FILE 1>"$STDOUT_FILE" 2>"$STDERR_FILE"
$ARG_CMD $ARG_FILE $ARG_ARGS 1>"$STDOUT_FILE" 2>"$STDERR_FILE"
RETCODE=$?
set -e

Expand Down Expand Up @@ -113,7 +117,7 @@ case "$OUTPUT_STDERR" in
;;
esac

if ! diff --color=auto -u "$STDOUT_FILE" "$EXPECTED_STDOUT_FILE"; then
if ! diff --color=auto -u "$EXPECTED_STDOUT_FILE" "$STDOUT_FILE"; then
echo '\nTEST FAILED'
exit 1
fi
Expand Down
2 changes: 1 addition & 1 deletion etc/vim/syntax/nkst.vim
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ if exists("b:current_syntax")
finish
endif

syn keyword nkstKeyword nullptr proc link const pub const import param call return context run var assign struct member if while addr deref export index defer scope
syn keyword nkstKeyword nullptr proc link const pub const import param call return context run var assign struct member if while addr deref export index defer scope nickl
syn keyword nkstKeyword add sub mul div mod bitand bitor xor lsh rsh and or not
syn keyword nkstKeyword eq ne lt le gt ge

Expand Down
3 changes: 2 additions & 1 deletion src/nkl_core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
set(LIB nkl_core)

add_library(${LIB}
add_library(${LIB} SHARED
src/compiler.cpp
src/compiler_api.c
src/compiler_state.cpp
src/nickl.c
src/types.c
Expand Down
17 changes: 9 additions & 8 deletions src/nkl_core/include/nkl/core/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "nkb/ir.h"
#include "nkl/core/nickl.h"
#include "ntk/atom.h"
#include "ntk/common.h"
#include "ntk/string.h"

#ifdef __cplusplus
Expand All @@ -19,18 +20,18 @@ typedef struct {
typedef struct NklCompiler_T *NklCompiler;
typedef struct NklModule_T *NklModule;

NklCompiler nkl_createCompiler(NklState nkl, NklTargetTriple target);
void nkl_freeCompiler(NklCompiler c);
NK_EXPORT NklCompiler nkl_createCompiler(NklState nkl, NklTargetTriple target);
NK_EXPORT void nkl_freeCompiler(NklCompiler c);

usize nkl_getCompileErrorCount(NklCompiler c);
NklError *nkl_getCompileErrorList(NklCompiler c);
NK_EXPORT usize nkl_getCompileErrorCount(NklCompiler c);
NK_EXPORT NklError *nkl_getCompileErrorList(NklCompiler c);

NklModule nkl_createModule(NklCompiler c);
NK_EXPORT NklModule nkl_createModule(NklCompiler c);

bool nkl_runModule(NklModule m);
bool nkl_writeModule(NklModule m, NkIrCompilerConfig conf);
NK_EXPORT bool nkl_runModule(NklModule m);
NK_EXPORT bool nkl_writeModule(NklModule m, NkIrCompilerConfig conf);

bool nkl_compileFile(NklModule m, NkString filename);
NK_EXPORT bool nkl_compileFile(NklModule m, NkString filename);

#ifdef __cplusplus
}
Expand Down
17 changes: 17 additions & 0 deletions src/nkl_core/include/nkl/core/compiler_api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef NKL_CORE_COMPILER_API_H_
#define NKL_CORE_COMPILER_API_H_

#include "nkl/core/nickl.h"
#include "ntk/common.h"

#ifdef __cplusplus
extern "C" {
#endif

NK_EXPORT StringSlice nickl_api_getCommandLineArgs(NklState nkl);

#ifdef __cplusplus
}
#endif

#endif // NKL_CORE_COMPILER_API_H_
18 changes: 10 additions & 8 deletions src/nkl_core/include/nkl/core/nickl.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@
extern "C" {
#endif

typedef NkSlice(NkString) StringSlice;

typedef struct NklState_T *NklState;

typedef NklTokenArray (*NklLexerProc)(NklState nkl, NkAllocator alloc, NkAtom file, NkString text);
typedef NklAstNodeArray (
*NklParserProc)(NklState nkl, NkAllocator alloc, NkAtom file, NkString text, NklTokenArray tokens);

NklState nkl_state_create(NklLexerProc lexer_proc, NklParserProc parser_proc);
void nkl_state_free(NklState nkl);
NK_EXPORT NklState nkl_state_create(StringSlice args, NklLexerProc lexer_proc, NklParserProc parser_proc);
NK_EXPORT void nkl_state_free(NklState nkl);

NklSource const *nkl_getSource(NklState nkl, NkAtom file);
NK_EXPORT NklSource const *nkl_getSource(NklState nkl, NkAtom file);

typedef struct NklError {
struct NklError *next;
Expand All @@ -40,13 +42,13 @@ typedef struct NklErrorState {
usize error_count;
} NklErrorState;

void nkl_errorStateEquip(NklErrorState *state);
void nkl_errorStateUnequip(void);
NK_EXPORT void nkl_errorStateEquip(NklErrorState *state);
NK_EXPORT void nkl_errorStateUnequip(void);

usize nkl_getErrorCount(void);
NK_EXPORT usize nkl_getErrorCount(void);

NK_PRINTF_LIKE(3) i32 nkl_reportError(NkAtom file, NklToken const *token, char const *fmt, ...);
i32 nkl_vreportError(NkAtom file, NklToken const *token, char const *fmt, va_list ap);
NK_EXPORT NK_PRINTF_LIKE(3) i32 nkl_reportError(NkAtom file, NklToken const *token, char const *fmt, ...);
NK_EXPORT i32 nkl_vreportError(NkAtom file, NklToken const *token, char const *fmt, va_list ap);

#ifdef __cplusplus
}
Expand Down
56 changes: 33 additions & 23 deletions src/nkl_core/include/nkl/core/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,28 +75,28 @@ typedef struct {
u8 flags;
} NklProcInfo;

void nkl_types_init(NklState nkl);
void nkl_types_free(NklState nkl);

nkltype_t nkl_get_any(NklState nkl, usize word_size);
nkltype_t nkl_get_array(NklState nkl, nkltype_t elem_type, usize elem_count);
nkltype_t nkl_get_bool(NklState nkl);
nkltype_t nkl_get_enum(NklState nkl, NklFieldArray fields);
nkltype_t nkl_get_numeric(NklState nkl, NkIrNumericValueType value_type);
nkltype_t nkl_get_int(NklState nkl, usize size, bool is_signed);
nkltype_t nkl_get_proc(NklState nkl, usize word_size, NklProcInfo info);
nkltype_t nkl_get_ptr(NklState nkl, usize word_size, nkltype_t target_type, bool is_const);
nkltype_t nkl_get_slice(NklState nkl, usize word_size, nkltype_t target_type, bool is_const);
nkltype_t nkl_get_struct(NklState nkl, NklFieldArray fields);
nkltype_t nkl_get_struct_packed(NklState nkl, NklFieldArray fields);
nkltype_t nkl_get_tuple(NklState nkl, NklTypeStridedArray types);
nkltype_t nkl_get_tupleEx(NklState nkl, nkltype_t const *types, usize count, usize stride);
nkltype_t nkl_get_tuple_packed(NklState nkl, NklTypeStridedArray types);
nkltype_t nkl_get_typeref(NklState nkl, usize word_size);
nkltype_t nkl_get_union(NklState nkl, NklFieldArray fields);
nkltype_t nkl_get_void(NklState nkl);

void nkl_type_inspect(nkltype_t type, NkStream out);
NK_EXPORT void nkl_types_init(NklState nkl);
NK_EXPORT void nkl_types_free(NklState nkl);

NK_EXPORT nkltype_t nkl_get_any(NklState nkl, usize word_size);
NK_EXPORT nkltype_t nkl_get_array(NklState nkl, nkltype_t elem_type, usize elem_count);
NK_EXPORT nkltype_t nkl_get_bool(NklState nkl);
NK_EXPORT nkltype_t nkl_get_enum(NklState nkl, NklFieldArray fields);
NK_EXPORT nkltype_t nkl_get_numeric(NklState nkl, NkIrNumericValueType value_type);
NK_EXPORT nkltype_t nkl_get_int(NklState nkl, usize size, bool is_signed);
NK_EXPORT nkltype_t nkl_get_proc(NklState nkl, usize word_size, NklProcInfo info);
NK_EXPORT nkltype_t nkl_get_ptr(NklState nkl, usize word_size, nkltype_t target_type, bool is_const);
NK_EXPORT nkltype_t nkl_get_slice(NklState nkl, usize word_size, nkltype_t target_type, bool is_const);
NK_EXPORT nkltype_t nkl_get_struct(NklState nkl, NklFieldArray fields);
NK_EXPORT nkltype_t nkl_get_struct_packed(NklState nkl, NklFieldArray fields);
NK_EXPORT nkltype_t nkl_get_tuple(NklState nkl, NklTypeStridedArray types);
NK_EXPORT nkltype_t nkl_get_tupleEx(NklState nkl, nkltype_t const *types, usize count, usize stride);
NK_EXPORT nkltype_t nkl_get_tuple_packed(NklState nkl, NklTypeStridedArray types);
NK_EXPORT nkltype_t nkl_get_typeref(NklState nkl, usize word_size);
NK_EXPORT nkltype_t nkl_get_union(NklState nkl, NklFieldArray fields);
NK_EXPORT nkltype_t nkl_get_void(NklState nkl);

NK_EXPORT void nkl_type_inspect(nkltype_t type, NkStream out);

NK_INLINE nktype_t nklt2nkirt(nkltype_t type) {
return &type->ir_type;
Expand Down Expand Up @@ -200,9 +200,19 @@ NK_INLINE usize nklt_struct_index(nkltype_t type, NkAtom name) {
return -1u;
}

NK_INLINE nkltype_t nklt_slice_ptrType(nkltype_t type) {
nk_assert(nklt_tclass(type) == NklType_Slice);
return nklt_struct_field(nklt_underlying(type), 0).type;
}

NK_INLINE nkltype_t nklt_slice_target(nkltype_t type) {
nk_assert(nklt_tclass(type) == NklType_Slice);
return nklt_ptr_target(nklt_struct_field(nklt_underlying(type), 0).type);
return nklt_ptr_target(nklt_slice_ptrType(type));
}

NK_INLINE bool nklt_slice_isConst(nkltype_t type) {
nk_assert(nklt_tclass(type) == NklType_Slice);
return nklt_ptr_isConst(nklt_slice_ptrType(type));
}

NK_INLINE usize nklt_tuple_size(nkltype_t type) {
Expand Down
70 changes: 61 additions & 9 deletions src/nkl_core/src/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -860,23 +860,45 @@ static Interm getMember(Context &ctx, Interm const &lhs, NkAtom name) {
}
}

static Interm getIndex(Context &ctx, Interm const &arr, Interm const &idx) {
switch (nklt_tclass(arr.type)) {
static Interm getIndex(Context &ctx, Interm const &lhs, Interm const &idx) {
switch (nklt_tclass(lhs.type)) {
case NklType_Array: {
// TODO: Optimize array indexing??
auto const elem_t = nklt_array_elemType(arr.type);
auto const data_ptr = asRef(ctx, makeInstr(nkir_make_lea(ctx.ir, {}, asRef(ctx, arr)), ctx.c->usize_t()));
auto const elem_t = nklt_array_elemType(lhs.type);
if (isValueKnown(idx)) {
auto const idx_val = nklval_as(usize, getValueFromInterm(ctx, idx));
auto lhs_ref = asRef(ctx, lhs);
lhs_ref.post_offset += idx_val * nklt_sizeof(elem_t);
return makeRef(cast(elem_t, lhs_ref));
} else {
auto const data_ptr =
asRef(ctx, makeInstr(nkir_make_lea(ctx.ir, {}, asRef(ctx, lhs)), ctx.c->usize_t()));
auto const elem_size = asRef(ctx, makeUsizeConst(ctx, nklt_sizeof(elem_t)));
auto const mul = nkir_make_mul(ctx.ir, {}, asRef(ctx, idx), elem_size);
auto const offset = asRef(ctx, makeInstr(mul, ctx.c->usize_t()));
auto const add = nkir_make_add(ctx.ir, {}, data_ptr, offset);
auto const elem_ptr_t = nkl_get_ptr(ctx.nkl, ctx.c->word_size, elem_t, false);
return deref(cast(elem_ptr_t, asRef(ctx, makeInstr(add, ctx.c->usize_t()))));
}
}

case NklType_Slice: {
auto const elem_t = nklt_slice_target(lhs.type);
auto const data_ptr = cast(ctx.c->usize_t(), asRef(ctx, lhs));
auto const elem_size = asRef(ctx, makeUsizeConst(ctx, nklt_sizeof(elem_t)));
auto const mul = nkir_make_mul(ctx.ir, {}, asRef(ctx, idx), elem_size);
auto const offset = asRef(ctx, makeInstr(mul, ctx.c->usize_t()));
auto const add = nkir_make_add(ctx.ir, {}, data_ptr, offset);
auto const elem_ptr_t = nkl_get_ptr(ctx.nkl, ctx.c->word_size, elem_t, false);
auto const elem_ptr_t = nklt_slice_ptrType(lhs.type);
return deref(cast(elem_ptr_t, asRef(ctx, makeInstr(add, ctx.c->usize_t()))));
}

case NklType_Pointer: {
return getIndex(ctx, deref(asRef(ctx, lhs)), idx);
}

default: {
NkStringBuilder sb{NKSB_INIT(nk_arena_getAllocator(ctx.scope_stack->temp_arena))};
nkl_type_inspect(arr.type, nksb_getStream(&sb));
nkl_type_inspect(lhs.type, nksb_getStream(&sb));
return error(ctx, "type `" NKS_FMT "` is not indexable", NKS_ARG(sb));
}
}
Expand Down Expand Up @@ -929,7 +951,7 @@ static Interm compileLvalueRef(Context &ctx, NklAstNode const &node) {
auto &arr_n = nextNode(node_it);
auto &idx_n = nextNode(node_it);

DEFINE(const arr, compile(ctx, arr_n, {.res_tclass = NklType_Array}));
DEFINE(const arr, compile(ctx, arr_n));
DEFINE(const idx, compile(ctx, idx_n, {ctx.c->usize_t()}));

return getIndex(ctx, arr, idx);
Expand Down Expand Up @@ -1089,6 +1111,11 @@ static Interm compileImpl(Context &ctx, NklAstNode const &node, CompileConfig co
return makeVoid(ctx);
}

// TODO: Usint *void as a nickl state ptr type for now
case n_nickl: {
return makeConst<void *>(ctx, nkl_get_ptr(ctx.nkl, ctx.c->word_size, ctx.c->void_t(), false), ctx.nkl);
}

#define COMPILE_NUM(NAME, IR_NAME) \
case NK_CAT(n_, NAME): { \
DEFINE(lhs, compile(ctx, nextNode(node_it), {.res_t = res_t, .res_tclass = NklType_Numeric})); \
Expand Down Expand Up @@ -1211,7 +1238,32 @@ static Interm compileImpl(Context &ctx, NklAstNode const &node, CompileConfig co
if (i == param_count) {
nkda_append(&arg_refs, nkir_makeVariadicMarkerRef(ctx.ir));
}
nkda_append(&arg_refs, asRef(ctx, args.data[i]));
auto arg_ref = asRef(ctx, args.data[i]);
if (nklt_proc_callConv(lhs.type) == NkCallConv_Cdecl && i >= param_count &&
nklt_tclass(args.data[i].type) == NklType_Numeric) {
// Variadic promotion
switch (nklt_numeric_valueType(args.data[i].type)) {
case Int8:
arg_ref = asRef(ctx, makeInstr(nkir_make_ext(ctx.ir, {}, arg_ref), ctx.c->i32_t()));
break;
case Uint8:
arg_ref = asRef(ctx, makeInstr(nkir_make_ext(ctx.ir, {}, arg_ref), ctx.c->u32_t()));
break;
case Int16:
arg_ref = asRef(ctx, makeInstr(nkir_make_ext(ctx.ir, {}, arg_ref), ctx.c->i32_t()));
break;
case Uint16:
arg_ref = asRef(ctx, makeInstr(nkir_make_ext(ctx.ir, {}, arg_ref), ctx.c->u32_t()));
break;
case Float32:
arg_ref = asRef(ctx, makeInstr(nkir_make_ext(ctx.ir, {}, arg_ref), ctx.c->f64_t()));
break;

default:
break;
}
}
nkda_append(&arg_refs, arg_ref);
}

return makeInstr(
Expand Down
7 changes: 7 additions & 0 deletions src/nkl_core/src/compiler_api.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "nkl/core/compiler_api.h"

#include "nickl_impl.h"

StringSlice nickl_api_getCommandLineArgs(NklState nkl) {
return nkl->cli_args;
}
3 changes: 2 additions & 1 deletion src/nkl_core/src/nickl.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static NkAtom const *Source_kv_GetKey(Source_kv const *item) {
}
NK_HASH_TREE_IMPL(FileMap, Source_kv, NkAtom, Source_kv_GetKey, nk_atom_hash, nk_atom_equal);

NklState nkl_state_create(NklLexerProc lexer_proc, NklParserProc parser_proc) {
NklState nkl_state_create(StringSlice args, NklLexerProc lexer_proc, NklParserProc parser_proc) {
#define XN(N, T) nk_atom_define(NK_CAT(n_, N), nk_cs2s(T));
#include "nodes.inl"

Expand All @@ -36,6 +36,7 @@ NklState nkl_state_create(NklLexerProc lexer_proc, NklParserProc parser_proc) {
.lexer_proc = lexer_proc,
.parser_proc = parser_proc,
.files = {0},
.cli_args = args,
};
nkl->files.alloc = nk_arena_getAllocator(&nkl->permanent_arena);

Expand Down
2 changes: 2 additions & 0 deletions src/nkl_core/src/nickl_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ typedef struct NklState_T {
NklParserProc parser_proc;

FileMap files;

StringSlice cli_args;
} NklState_T;

#ifdef __cplusplus
Expand Down
2 changes: 2 additions & 0 deletions src/nkl_core/src/nodes.inl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

X(null)

X(nickl)

X(any_t)
X(bool)
X(nullptr)
Expand Down
Loading

0 comments on commit caa5f3c

Please sign in to comment.