Skip to content

Commit

Permalink
fix module loading; updated import statement
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiosvm committed Aug 7, 2023
1 parent 06c24a7 commit 9090780
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 46 deletions.
3 changes: 2 additions & 1 deletion docs/grammar.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ statement ::= import_statement
| block
import_statement ::= 'import' name ( 'as' name )? ';'
| 'import' '{' name ( ',' name )* '}' 'from' name ';'
| 'import' STRING 'as' name ';'
| 'import' '{' name ( ',' name )* '}' 'from' ( name | STRING ) ';'
variable_declaration ::= 'let' name '=' expression
| 'mut' name ( '=' expression )?
Expand Down
3 changes: 2 additions & 1 deletion docs/grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
chunk ::= stmt* EOF

stmt ::= 'import' NAME ( 'as' NAME )? ';'
| 'import' '{' NAME ( ',' NAME )* '}' 'from' NAME ';'
| 'import' STRING 'as' NAME ';'
| 'import' '{' NAME ( ',' NAME )* '}' 'from' ( NAME | STRING ) ';'
| var_decl ';'
| assign_call ';'
| 'struct' NAME '{' ( STRING | NAME ( ',' STRING | NAME )* )? '}'
Expand Down
2 changes: 1 addition & 1 deletion examples/import.hk
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//

import os;
import { foo, bar } from module;
import { foo, bar } from "module.hk";

println(os.clock());
println(foo());
Expand Down
5 changes: 4 additions & 1 deletion src/builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,16 @@ static inline void string_to_double(HkState *state, HkString *str, double *resul
static inline HkArray *split(HkString *str, HkString *sep)
{
HkArray *arr = hk_array_new();
char *cur = str->chars;
// TODO: Do not use strtok_r and do not copy the string
HkString *_str = hk_string_copy(str);
char *cur = _str->chars;
char *tk;
while ((tk = strtok_r(cur, sep->chars, &cur)))
{
HkValue elem = hk_string_value(hk_string_from_chars(-1, tk));
hk_array_inplace_add_element(arr, elem);
}
hk_string_free(_str);
return arr;
}

Expand Down
33 changes: 25 additions & 8 deletions src/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,23 @@ static void compile_import_statement(Compiler *comp)
hk_chunk_emit_opcode(chunk, HK_OP_LOAD_MODULE);
return;
}
if (match(scan, TOKEN_STRING))
{
Token tk = scan->token;
scanner_next_token(scan);
uint8_t index = add_string_constant(comp, &tk);
hk_chunk_emit_opcode(chunk, HK_OP_CONSTANT);
hk_chunk_emit_byte(chunk, index);
consume(comp, TOKEN_AS);
if (!match(scan, TOKEN_NAME))
syntax_error_unexpected(comp);
tk = scan->token;
scanner_next_token(scan);
define_local(comp, &tk, false);
consume(comp, TOKEN_SEMICOLON);
hk_chunk_emit_opcode(chunk, HK_OP_LOAD_MODULE);
return;
}
if (match(scan, TOKEN_LBRACE))
{
scanner_next_token(scan);
Expand Down Expand Up @@ -553,7 +570,7 @@ static void compile_import_statement(Compiler *comp)
}
consume(comp, TOKEN_RBRACE);
consume(comp, TOKEN_FROM);
if (!match(scan, TOKEN_NAME))
if (!match(scan, TOKEN_NAME) && !match(scan, TOKEN_STRING))
syntax_error_unexpected(comp);
tk = scan->token;
scanner_next_token(scan);
Expand Down Expand Up @@ -605,7 +622,7 @@ static void compile_constant_declaration(Compiler *comp)
{
if (!match(scan, TOKEN_NAME))
syntax_error_unexpected(comp);
// FIX: This is a bug, we should not define the local here
// FIXME: This is a bug, we should not define the local here
define_local(comp, &scan->token, false);
}
scanner_next_token(scan);
Expand All @@ -625,7 +642,7 @@ static void compile_constant_declaration(Compiler *comp)
syntax_error_unexpected(comp);
Token tk = scan->token;
scanner_next_token(scan);
// FIX: This is a bug, we should not define the local here
// FIXME: This is a bug, we should not define the local here
define_local(comp, &tk, false);
uint8_t index = add_string_constant(comp, &tk);
hk_chunk_emit_opcode(chunk, HK_OP_CONSTANT);
Expand All @@ -638,7 +655,7 @@ static void compile_constant_declaration(Compiler *comp)
syntax_error_unexpected(comp);
Token tk = scan->token;
scanner_next_token(scan);
// FIX: This is a bug, we should not define the local here
// FIXME: This is a bug, we should not define the local here
define_local(comp, &tk, false);
uint8_t index = add_string_constant(comp, &tk);
hk_chunk_emit_opcode(chunk, HK_OP_CONSTANT);
Expand Down Expand Up @@ -684,7 +701,7 @@ static void compile_variable_declaration(Compiler *comp)
{
if (!match(scan, TOKEN_NAME))
syntax_error_unexpected(comp);
// FIX: This is a bug, we should not define the local here
// FIXME: This is a bug, we should not define the local here
define_local(comp, &scan->token, false);
}
scanner_next_token(scan);
Expand All @@ -698,7 +715,7 @@ static void compile_variable_declaration(Compiler *comp)
{
if (!match(scan, TOKEN_NAME))
syntax_error_unexpected(comp);
// FIX: This is a bug, we should not define the local here
// FIXME: This is a bug, we should not define the local here
define_local(comp, &scan->token, false);
}
scanner_next_token(scan);
Expand All @@ -718,7 +735,7 @@ static void compile_variable_declaration(Compiler *comp)
syntax_error_unexpected(comp);
Token tk = scan->token;
scanner_next_token(scan);
// FIX: This is a bug, we should not define the local here
// FIXME: This is a bug, we should not define the local here
define_local(comp, &tk, true);
uint8_t index = add_string_constant(comp, &tk);
hk_chunk_emit_opcode(chunk, HK_OP_CONSTANT);
Expand All @@ -731,7 +748,7 @@ static void compile_variable_declaration(Compiler *comp)
syntax_error_unexpected(comp);
Token tk = scan->token;
scanner_next_token(scan);
// FIX: This is a bug, we should not define the local here
// FIXME: This is a bug, we should not define the local here
define_local(comp, &tk, true);
uint8_t index = add_string_constant(comp, &tk);
hk_chunk_emit_opcode(chunk, HK_OP_CONSTANT);
Expand Down
77 changes: 55 additions & 22 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#define WILDCARD "?"

#define LIB_DIR "lib"
#define LIB_PREFIX "lib"
#define LIB_POSTFIX "_mod"

#define SRC_EXT ".hk"
Expand All @@ -62,13 +61,16 @@
#endif

static StringMap moduleCache;
static HkString *path = NULL;

static inline const char *get_home_dir(void);
static inline const char *get_default_home_dir(void);
static inline HkString *get_path(void);
static inline HkString *get_default_path(void);
static inline HkString *path_match(HkString *path, HkString *name);
static inline void load_module(HkState *state, HkString *name);
static inline HkString *path_match(HkString *path, HkString *name, HkString *currFile);
static inline bool is_relative(char *filename);
static inline HkString *get_module_file(HkString *relFile, HkString *currFile);
static inline void load_module(HkState *state, HkString *name, HkString *currFile);
static inline bool is_source_module(char *filename);
static inline void load_source_module(HkState *state, HkString *file, HkString *name);
static inline void load_native_module(HkState *state, HkString *file, HkString *name);
Expand Down Expand Up @@ -100,20 +102,24 @@ static inline const char *get_default_home_dir(void)

static inline HkString *get_path(void)
{
const char *_path = getenv(PATH_ENV_VAR);
if (_path)
return hk_string_from_chars(-1, _path);
return get_default_path();
if (!path)
{
const char *_path = getenv(PATH_ENV_VAR);
path = _path ? hk_string_from_chars(-1, _path) : get_default_path();
}
return path;
}

static inline HkString *get_default_path(void)
{
HkString *path = hk_string_new();
hk_string_inplace_concat_chars(path, -1, WILDCARD);
hk_string_inplace_concat_chars(path, -1, PATH_SEP);

hk_string_inplace_concat_chars(path, -1, get_home_dir());
hk_string_inplace_concat_chars(path, -1, DIR_SEP);
hk_string_inplace_concat_chars(path, -1, LIB_DIR);
hk_string_inplace_concat_chars(path, -1, DIR_SEP);
hk_string_inplace_concat_chars(path, -1, LIB_PREFIX);
hk_string_inplace_concat_chars(path, -1, WILDCARD);
hk_string_inplace_concat_chars(path, -1, LIB_POSTFIX);
hk_string_inplace_concat_chars(path, -1, LIB_EXT);
Expand All @@ -130,36 +136,61 @@ static inline HkString *get_default_path(void)
return path;
}

static inline HkString *path_match(HkString *path, HkString *name)
static inline HkString *path_match(HkString *path, HkString *name, HkString *currFile)
{
HkString *sep = hk_string_from_chars(-1, PATH_SEP);
HkArray *entries = hk_string_split(path, sep);
HkArray *patterns = hk_string_split(path, sep);
hk_string_free(sep);
HkString *wc = hk_string_from_chars(-1, WILDCARD);
int n = entries->length;
int n = patterns->length;
for (int i = 0; i < n; ++i)
{
HkValue elem = hk_array_get_element(entries, i);
HkString *entry = hk_as_string(elem);
HkString *file = hk_string_replace_all(entry, wc, name);
HkValue elem = hk_array_get_element(patterns, i);
HkString *pattern = hk_as_string(elem);
HkString *file = hk_string_replace_all(pattern, wc, name);
if (is_relative(file->chars))
{
HkString *_file = get_module_file(file, currFile);
hk_string_free(file);
file = _file;
}
if (file_exists(file->chars))
{
hk_string_free(wc);
hk_array_free(entries);
hk_array_free(patterns);
return file;
}
hk_string_free(file);
}
hk_string_free(wc);
hk_array_free(entries);
hk_array_free(patterns);
return NULL;
}

static inline void load_module(HkState *state, HkString *name)
static inline bool is_relative(char *filename)
{
return filename[0] != DIR_SEP[0];
}

static inline HkString *get_module_file(HkString *relFile, HkString *currFile)
{
char *chars = currFile->chars;
char *end = strrchr(chars, DIR_SEP[0]);
if (end)
{
int length = (int) (end - chars);
HkString *file = hk_string_from_chars(length, chars);
hk_string_inplace_concat_chars(file, -1, DIR_SEP);
hk_string_inplace_concat(file, relFile);
return file;
}
return hk_string_copy(relFile);
}

static inline void load_module(HkState *state, HkString *name, HkString *currFile)
{
HkString *path = get_path();
HkString *file = path_match(path, name);
hk_string_free(path);
HkString *file = path_match(path, name, currFile);
if (!file)
{
hk_state_runtime_error(state, "cannot find module `%.*s`",
Expand Down Expand Up @@ -265,24 +296,26 @@ void module_cache_init(void)
void module_cache_deinit(void)
{
string_map_deinit(&moduleCache);
if (path)
hk_string_free(path);
}

void module_load(HkState *state)
void module_load(HkState *state, HkString *currFile)
{
HkValue *slots = &state->stackSlots[state->stackTop];
HkValue val = slots[0];
hk_assert(hk_is_string(val), "module name must be a string");
HkString *name = hk_as_string(val);
HkValue module;
// FIXME: Do cache using absolute file path instead of module name
if (module_cache_get(name, &module))
{
hk_value_incr_ref(module);
slots[0] = module;
--state->stackTop;
hk_string_release(name);
return;
}
load_module(state, name);
load_module(state, name, currFile);
hk_return_if_not_ok(state);
module_cache_put(name, state->stackSlots[state->stackTop]);
slots[0] = state->stackSlots[state->stackTop];
Expand Down
2 changes: 1 addition & 1 deletion src/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@

void module_cache_init(void);
void module_cache_deinit(void);
void module_load(HkState *state);
void module_load(HkState *state, HkString *currFile);

#endif // MODULE_H
2 changes: 1 addition & 1 deletion src/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -1772,7 +1772,7 @@ static inline void call_function(HkState *state, HkValue *locals, HkClosure *cl,
goto end;
break;
case HK_OP_LOAD_MODULE:
module_load(state);
module_load(state, fn->file);
if (!hk_state_is_ok(state))
goto end;
break;
Expand Down
32 changes: 22 additions & 10 deletions src/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
static inline HkString *string_allocate(int minCapacity);
static inline void add_char(HkString *str, char c);
static inline uint32_t hash(int length, char *chars);
static inline int index_of(char *chars, int length, char *sub);
static inline int index_of(char *chars, int subLength, char *sub);

static inline HkString *string_allocate(int minCapacity)
{
Expand Down Expand Up @@ -50,11 +50,16 @@ static inline uint32_t hash(int length, char *chars)
return hash;
}

static inline int index_of(char *chars, int length, char *sub)
static inline int index_of(char *chars, int subLength, char *sub)
{
for (int i = 0; chars[i + length]; ++i)
if (!memcmp(&chars[i], sub, length))
int i = 0;
for (; chars[i + subLength]; ++i)
{
if (!memcmp(&chars[i], sub, subLength))
return i;
}
if (!memcmp(&chars[i], sub, subLength))
return i;
return -1;
}

Expand Down Expand Up @@ -204,18 +209,22 @@ HkString *hk_string_replace_all(HkString *str, HkString *sub1, HkString *sub2)
return hk_string_copy(str);
HkString *result = string_allocate(0);
result->length = 0;
char *chars = str->chars;
char *strChars = str->chars;
char *subChars = sub1->chars;
for (;;)
{
int index = index_of(chars, subLength, subChars);
if (!strLength || strLength > str->length)
break;
int index = index_of(strChars, subLength, subChars);
if (index == -1)
break;
hk_string_inplace_concat_chars(result, index, chars);
hk_string_inplace_concat_chars(result, index, strChars);
hk_string_inplace_concat(result, sub2);
chars += index + subLength;
int count = index + subLength;
strLength -= count;
strChars += count;
}
hk_string_inplace_concat_chars(result, -1, chars);
hk_string_inplace_concat_chars(result, -1, strChars);
return result;
}

Expand All @@ -238,13 +247,16 @@ HkString *hk_string_slice(HkString *str, int start, int stop)
HkArray *hk_string_split(HkString *str, HkString *sep)
{
HkArray *arr = hk_array_new();
char *cur = str->chars;
// TODO: Do not use strtok_r and do not copy the string
HkString *_str = hk_string_copy(str);
char *cur = _str->chars;
char *tk;
while ((tk = strtok_r(cur, sep->chars, &cur)))
{
HkValue elem = hk_string_value(hk_string_from_chars(-1, tk));
hk_array_inplace_add_element(arr, elem);
}
hk_string_free(_str);
return arr;
}

Expand Down
Loading

0 comments on commit 9090780

Please sign in to comment.