11 #include <sys/utsname.h>
12 #include <sys/ioctl.h>
24 extern char ** environ;
26 #define DO_KEY(key) krk_attachNamedObject(AS_DICT(result), #key, (KrkObj*)krk_copyString(buf. key, strlen(buf .key)))
27 #define S_KEY(key,val) krk_attachNamedObject(AS_DICT(result), #key, (KrkObj*)val);
32 if (uname(&buf) < 0)
return NONE_VAL();
50 TCHAR buffer[256] = TEXT(
"");
51 DWORD dwSize =
sizeof(buffer);
52 GetComputerName(buffer, &dwSize);
54 OSVERSIONINFOA versionInfo = {0};
55 versionInfo.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
56 GetVersionExA(&versionInfo);
58 if (versionInfo.dwMajorVersion == 10) {
59 S_KEY(release,S(
"10"));
60 }
else if (versionInfo.dwMajorVersion == 6) {
61 if (versionInfo.dwMinorVersion == 3) {
62 S_KEY(release,S(
"8.1"));
63 }
else if (versionInfo.dwMinorVersion == 2) {
64 S_KEY(release,S(
"8.0"));
65 }
else if (versionInfo.dwMinorVersion == 1) {
66 S_KEY(release,S(
"7"));
67 }
else if (versionInfo.dwMinorVersion == 0) {
68 S_KEY(release,S(
"Vista"));
71 S_KEY(release,S(
"XP or earlier"));
75 size_t len = snprintf(tmp, 256,
"%ld", versionInfo.dwBuildNumber);
78 if (
sizeof(
void *) == 8) {
79 S_KEY(machine,S(
"x64"));
81 S_KEY(machine,S(
"x86"));
84 S_KEY(sysname,S(
"Windows"));
91 #define AS_Environ(o) (AS_INSTANCE(o))
92 #define IS_Environ(o) (krk_isInstanceOf(o,KRK_BASE_CLASS(Environ)))
93 #define CURRENT_CTYPE KrkInstance*
100 char * tmp = malloc(len);
101 snprintf(tmp, len,
"%s=%s", key->
chars, val->
chars);
106 KRK_Method(Environ,__setitem__) {
107 METHOD_TAKES_EXACTLY(2);
110 int r = _setVar(key,val);
123 unsetenv(str->
chars);
125 size_t len = str->
length + 2;
126 char * tmp = malloc(len);
127 snprintf(tmp, len,
"%s", str->
chars);
133 KRK_Method(Environ,__delitem__) {
134 METHOD_TAKES_EXACTLY(1);
148 BIND_METHOD(Environ,__setitem__);
149 BIND_METHOD(Environ,__delitem__);
157 environObj->
_class = Environ;
164 if (!environ)
return;
166 char ** env = environ;
167 for (; *env; env++) {
168 const char * equals = strchr(*env,
'=');
169 if (!equals)
continue;
171 size_t len = strlen(*env);
172 size_t keyLen = equals - *env;
173 size_t valLen = len - keyLen - 1;
180 krk_tableSet(AS_DICT(OBJECT_VAL(environObj)), key, val);
187 KRK_Function(system) {
189 if (!
krk_parseArgs(
"s",(
const char*[]){
"command"},&cmd))
return NONE_VAL();
190 return INTEGER_VAL(system(cmd));
193 KRK_Function(getcwd) {
194 FUNCTION_TAKES_NONE();
196 if (!getcwd(buf, 4096))
return krk_runtimeError(KRK_EXC(OSError),
"%s", strerror(errno));
200 KRK_Function(chdir) {
202 if (!
krk_parseArgs(
"s",(
const char*[]){
"path"}, &path))
return NONE_VAL();
203 if (chdir(path))
return krk_runtimeError(KRK_EXC(OSError),
"%s", strerror(errno));
207 KRK_Function(getpid) {
208 FUNCTION_TAKES_NONE();
209 return INTEGER_VAL(getpid());
212 KRK_Function(strerror) {
214 if (!
krk_parseArgs(
"i",(
const char*[]){
"errnum"},&errnum))
return NONE_VAL();
215 char *s = strerror(errnum);
216 if (!s)
return NONE_VAL();
220 KRK_Function(access) {
223 if (!
krk_parseArgs(
"si",(
const char*[]){
"pathname",
"mode"},&path,&mask))
return NONE_VAL();
224 if (access(path, mask) == 0)
return BOOLEAN_VAL(1);
225 return BOOLEAN_VAL(0);
228 KRK_Function(abort) {
234 if (!
krk_parseArgs(
"i",(
const char*[]){
"status"},&status))
return NONE_VAL();
238 KRK_Function(remove) {
240 if (!
krk_parseArgs(
"s",(
const char*[]){
"path"}, &path))
return NONE_VAL();
241 if (remove(path) != 0) {
247 KRK_Function(truncate) {
250 if (!
krk_parseArgs(
"sn",(
const char*[]){
"path",
"length"}, &path, &length))
return NONE_VAL();
251 if (truncate(path, length) != 0) {
259 if (!
krk_parseArgs(
"i",(
const char*[]){
"fd"}, &fd))
return NONE_VAL();
260 int result = dup(fd);
264 return INTEGER_VAL(result);
269 if (!
krk_parseArgs(
"ii",(
const char*[]){
"fd",
"fd2"}, &fd, &fd2))
return NONE_VAL();
270 int result = dup2(fd,fd2);
274 return INTEGER_VAL(result);
277 KRK_Function(isatty) {
279 if (!
krk_parseArgs(
"i",(
const char*[]){
"fd"}, &fd))
return NONE_VAL();
280 return BOOLEAN_VAL(isatty(fd));
283 KRK_Function(lseek) {
286 if (!
krk_parseArgs(
"ini",(
const char*[]){
"fd",
"offset",
"how"}, &fd, &offset, &how))
return NONE_VAL();
287 off_t result = lseek(fd,offset,how);
291 return INTEGER_VAL(result);
298 if (!
krk_parseArgs(
"si|i",(
const char*[]){
"path",
"flags",
"mode"}, &path, &flags, &mode))
return NONE_VAL();
299 int result = open(path, flags, mode);
303 return INTEGER_VAL(result);
306 KRK_Function(close) {
308 if (!
krk_parseArgs(
"i",(
const char*[]){
"fd"}, &fd))
return NONE_VAL();
309 if (close(fd) == -1) {
316 #define mkdir(p,m) mkdir(p); (void)m
318 KRK_Function(mkdir) {
321 if (!
krk_parseArgs(
"s|i",(
const char*[]){
"path",
"mode"}, &path, &mode))
return NONE_VAL();
322 int result = mkdir(path, mode);
332 if (!
krk_parseArgs(
"in",(
const char*[]){
"fd",
"count"}, &fd, &count))
return NONE_VAL();
334 uint8_t * tmp = malloc(count);
335 ssize_t result = read(fd,tmp,count);
347 #define IS_bytes(o) IS_BYTES(o)
348 #define AS_bytes(o) AS_BYTES(o)
351 KRK_Function(write) {
354 if (!
krk_parseArgs(
"iO!",(
const char*[]){
"fd",
"buf"}, &fd, KRK_BASE_CLASS(bytes), &buf))
return NONE_VAL();
360 return INTEGER_VAL(result);
365 FUNCTION_TAKES_NONE();
367 if (pipe(fds) == -1) {
371 AS_TUPLE(
krk_peek(0))->values.values[0] = INTEGER_VAL(fds[0]);
372 AS_TUPLE(
krk_peek(0))->values.values[1] = INTEGER_VAL(fds[1]);
373 AS_TUPLE(
krk_peek(0))->values.count = 2;
378 FUNCTION_TAKES_EXACTLY(2);
381 if (!
krk_parseArgs(
"ni",(
const char*[]){
"pid",
"sig"}, &pid, &sig))
return NONE_VAL();
383 int result = kill(pid, sig);
387 return INTEGER_VAL(result);
391 FUNCTION_TAKES_NONE();
392 return INTEGER_VAL(fork());
395 KRK_Function(symlink) {
398 if (!
krk_parseArgs(
"ss",(
const char*[]){
"target",
"linkpath"}, &src, &dst))
return NONE_VAL();
400 if (symlink(src, dst) != 0) {
406 KRK_Function(tcgetpgrp) {
408 if (!
krk_parseArgs(
"i",(
const char*[]){
"fd"}, &fd))
return NONE_VAL();
409 int result = tcgetpgrp(fd);
413 return INTEGER_VAL(result);
416 KRK_Function(tcsetpgrp) {
419 if (!
krk_parseArgs(
"in",(
const char*[]){
"fd",
"pgrp"}, &fd, &pgrp))
return NONE_VAL();
420 int result = tcsetpgrp(fd,pgrp);
427 KRK_Function(ttyname) {
429 if (!
krk_parseArgs(
"i",(
const char*[]){
"fd"}, &fd))
return NONE_VAL();
430 char * result = ttyname(fd);
437 KRK_Function(get_terminal_size) {
439 if (!
krk_parseArgs(
"|i",(
const char*[]){
"fd"}, &fd))
return NONE_VAL();
442 int res = ioctl(fd, TIOCGWINSZ, &wsz);
449 AS_TUPLE(
krk_peek(0))->values.values[0] = INTEGER_VAL(wsz.ws_col);
450 AS_TUPLE(
krk_peek(0))->values.values[1] = INTEGER_VAL(wsz.ws_row);
451 AS_TUPLE(
krk_peek(0))->values.count = 2;
456 static int makeArgs(
int count,
const KrkValue * values,
char *** argsOut,
const char * _method_name) {
457 char ** out = malloc(
sizeof(
char*)*(count+1));
458 for (
int i = 0; i < count; ++i) {
459 if (!IS_STRING(values[i])) {
461 TYPE_ERROR(str,values[i]);
464 out[i] = AS_CSTRING(values[i]);
471 KRK_Function(execl) {
472 FUNCTION_TAKES_AT_LEAST(1);
475 if (makeArgs(argc-1,&argv[1],&args,_method_name))
return NONE_VAL();
476 if (execv(path->chars, args) == -1) {
480 return krk_runtimeError(KRK_EXC(OSError),
"Expected to not return from exec, but did.");
483 KRK_Function(execlp) {
484 FUNCTION_TAKES_AT_LEAST(1);
487 if (makeArgs(argc-1,&argv[1],&args,_method_name))
return NONE_VAL();
488 if (execvp(filename->chars, args) == -1) {
492 return krk_runtimeError(KRK_EXC(OSError),
"Expected to not return from exec, but did.");
495 KRK_Function(execle) {
496 FUNCTION_TAKES_AT_LEAST(1);
498 CHECK_ARG((argc-1),list,
KrkList*,envp);
501 if (makeArgs(argc-2,&argv[1],&args,_method_name))
return NONE_VAL();
502 if (makeArgs(envp->values.count, envp->values.values,&env,_method_name)) {
506 if (execve(path->chars, args, env) == -1) {
511 return krk_runtimeError(KRK_EXC(OSError),
"Expected to not return from exec, but did.");
514 KRK_Function(execv) {
515 FUNCTION_TAKES_EXACTLY(2);
517 CHECK_ARG(1,list,
KrkList*,args);
519 if (makeArgs(args->values.count, args->values.values, &argp,_method_name))
return NONE_VAL();
520 if (execv(filename->chars, argp) == -1) {
524 return krk_runtimeError(KRK_EXC(OSError),
"Expected to not return from exec, but did.");
527 KRK_Function(execvp) {
528 FUNCTION_TAKES_EXACTLY(2);
530 CHECK_ARG(1,list,
KrkList*,args);
532 if (makeArgs(args->values.count, args->values.values, &argp,_method_name))
return NONE_VAL();
533 if (execvp(path->chars, argp) == -1) {
537 return krk_runtimeError(KRK_EXC(OSError),
"Expected to not return from exec, but did.");
540 #define SET(thing) krk_attachNamedValue(&out->fields, #thing, INTEGER_VAL(buf. thing))
542 #define STAT_STRUCT struct __stat64
545 #define STAT_STRUCT struct stat
549 if (!
krk_parseArgs(
"s",(
const char*[]){
"path"}, &path))
return NONE_VAL();
552 int result = stat(path, &buf);
574 #define IS_stat_result(o) (krk_isInstanceOf(o,KRK_BASE_CLASS(stat_result)))
575 #define AS_stat_result(o) AS_INSTANCE(o)
576 #define CURRENT_NAME self
578 #define getProp(name) \
579 KrkValue name = NONE_VAL(); \
580 krk_tableGet(&self->fields, OBJECT_VAL(S(#name)), &name); \
581 if (!IS_INTEGER(name)) return krk_runtimeError(vm.exceptions->valueError, "stat_result is invalid")
583 KRK_Method(stat_result,__repr__) {
593 char * buf = malloc(1024);
594 size_t len = snprintf(buf,1024,
603 (
int)AS_INTEGER(st_dev),
604 (
int)AS_INTEGER(st_ino),
605 (
int)AS_INTEGER(st_mode),
606 (
int)AS_INTEGER(st_nlink),
607 (
int)AS_INTEGER(st_uid),
608 (
int)AS_INTEGER(st_gid),
609 (
int)AS_INTEGER(st_size));
611 if (len > 1023) len = 1023;
617 KRK_Function(S_ISBLK) {
619 if (!
krk_parseArgs(
"i",(
const char*[]){
"mode"},&mode))
return NONE_VAL();
620 return INTEGER_VAL(S_ISBLK(mode));
622 KRK_Function(S_ISCHR) {
624 if (!
krk_parseArgs(
"i",(
const char*[]){
"mode"},&mode))
return NONE_VAL();
625 return INTEGER_VAL(S_ISCHR(mode));
627 KRK_Function(S_ISDIR) {
629 if (!
krk_parseArgs(
"i",(
const char*[]){
"mode"},&mode))
return NONE_VAL();
630 return INTEGER_VAL(S_ISDIR(mode));
632 KRK_Function(S_ISFIFO) {
634 if (!
krk_parseArgs(
"i",(
const char*[]){
"mode"},&mode))
return NONE_VAL();
635 return INTEGER_VAL(S_ISFIFO(mode));
637 KRK_Function(S_ISREG) {
639 if (!
krk_parseArgs(
"i",(
const char*[]){
"mode"},&mode))
return NONE_VAL();
640 return INTEGER_VAL(S_ISREG(mode));
643 KRK_Function(S_ISLNK) {
645 if (!
krk_parseArgs(
"i",(
const char*[]){
"mode"},&mode))
return NONE_VAL();
646 return INTEGER_VAL(S_ISLNK(mode));
648 KRK_Function(S_ISSOCK) {
650 if (!
krk_parseArgs(
"i",(
const char*[]){
"mode"},&mode))
return NONE_VAL();
651 return INTEGER_VAL(S_ISSOCK(mode));
660 KRK_DOC(module,
"@brief Provides access to low-level system operations.");
682 #define DO_INT(name) krk_attachNamedValue(&module->fields, #name, INTEGER_VAL(name))
719 KRK_DOC(BIND_FUNC(module,uname),
720 "@brief Returns a @ref dict of attributes describing the current platform.\n\n"
721 "On POSIX platforms, the result should match the contents and layout of a standard @c uname() call. "
722 "On Windows, values are synthesized from available information.");
723 KRK_DOC(BIND_FUNC(module,system),
724 "@brief Call the system shell.\n"
726 "Runs @p cmd using the system shell and returns the platform-dependent return value.");
727 KRK_DOC(BIND_FUNC(module,getcwd),
728 "@brief Get the name of the current working directory.");
729 KRK_DOC(BIND_FUNC(module,chdir),
730 "@brief Change the current working directory.\n"
731 "@arguments newcwd\n\n"
732 "Attempts to change the working directory to @p newcwd. Raises @ref OSError on failure.");
733 KRK_DOC(BIND_FUNC(module,getpid),
734 "@brief Obtain the system process identifier.");
735 KRK_DOC(BIND_FUNC(module,strerror),
736 "@brief Convert an integer error code to a string.\n"
737 "@arguments errorno\n\n"
738 "Provides the string description for the error code specified by @p errorno.");
739 KRK_DOC(BIND_FUNC(module,abort),
740 "@brief Abort the current process.\n\n"
741 "@bsnote{This will exit the interpreter without calling cleanup routines.}");
742 KRK_DOC(BIND_FUNC(module,exit),
743 "@brief Exit the current process.\n\n"
744 "@bsnote{This will exit the interpreter without calling cleanup routines.}");
745 KRK_DOC(BIND_FUNC(module,remove),
746 "@brief Delete a file.\n"
747 "@arguments path\n\n"
748 "Attempts to delete the file at @p path.");
749 KRK_DOC(BIND_FUNC(module,truncate),
750 "@brief Resize a file.\n"
751 "@arguments path,length\n\n"
752 "Attempts to resize the file at @p path to @p length bytes.");
754 "@brief Duplicate a file descriptor.\n"
756 "Returns a new file descriptor pointing to the same file as @p fd.");
757 KRK_DOC(BIND_FUNC(module,dup2),
758 "@brief Duplicate a file descriptor.\n"
759 "@arguments oldfd,newfd\n\n"
760 "Like @ref dup but the new file descriptor is placed at @p newfd.\n");
761 KRK_DOC(BIND_FUNC(module,isatty),
762 "@brief Determine if a file descriptor is a terminal.\n"
764 "Returns a @ref bool indicating whether the open file descriptor @p fd refers to a terminal.");
765 KRK_DOC(BIND_FUNC(module,lseek),
766 "@brief Seek an open file descriptor.\n"
767 "@arguments fd,pos,how\n\n"
768 "Seeks the open file descriptor @p fd by @p pos bytes as specified in @p how. "
769 "Use the values @c SEEK_SET, @c SEEK_CUR, and @c SEEK_END for @p how.");
770 KRK_DOC(BIND_FUNC(module,open),
771 "@brief Open a file.\n"
772 "@arguments path,flags,mode=0o777\n\n"
773 "Opens the file at @p path with the specified @p flags and @p mode. Returns a file descriptor.\n\n"
774 "@bsnote{Not to be confused with <a class=\"el\" href=\"mod_fileio.html#open\">fileio.open</a>}");
775 KRK_DOC(BIND_FUNC(module,close),
776 "@brief Close an open file descriptor.\n"
778 KRK_DOC(BIND_FUNC(module,read),
779 "@brief Read from an open file descriptor.\n"
780 "@arguments fd,n\n\n"
781 "Reads at most @p n bytes from the open file descriptor @p fd.");
782 KRK_DOC(BIND_FUNC(module,write),
783 "@brief Write to an open file descriptor.\n"
784 "@arguments fd,data\n\n"
785 "Writes the @ref bytes object @p data to the open file descriptor @p fd.");
786 KRK_DOC(BIND_FUNC(module,mkdir),
787 "@brief Create a directory.\n"
788 "@arguments path,mode=0o777\n\n"
789 "Creates a directory at @p path.");
791 KRK_DOC(BIND_FUNC(module,execl),
792 "@brief Replace the current process.\n"
793 "@arguments path,[args...]\n\n"
794 "The @c exec* family of functions replaces the calling process's image with a new one. "
795 "@c execl takes a @p path to a binary and an arbitrary number of @ref str arguments to "
796 "pass to the new executable.");
797 KRK_DOC(BIND_FUNC(module,execle),
798 "@brief Replace the current process.\n"
799 "@arguments path,[args...],env\n\n"
800 "The @c exec* family of functions replaces the calling process's image with a new one. "
801 "@c execle takes a @p path to a binary, an arbitrary number of @ref str arguments to "
802 "pass to the new executable, and @ref list of @c 'KEY=VALUE' pairs to set as the new "
804 KRK_DOC(BIND_FUNC(module,execlp),
805 "@brief Replace the current process.\n"
806 "@arguments filename,[args...]\n\n"
807 "The @c exec* family of functions replaces the calling process's image with a new one. "
808 "@c execlp takes a @p filename of a binary and an arbitrary number of @ref str arguments to "
809 "pass to the new executable. @p filename will be searched for in @c $PATH.");
810 KRK_DOC(BIND_FUNC(module,execv),
811 "@brief Replace the current process.\n"
812 "@arguments path,args\n\n"
813 "The @c exec* family of functions replaces the calling process's image with a new one. "
814 "@c execv takes a @p path to a binary and a @ref list @p args of @ref str arguments to "
815 "pass to the new executable.");
816 KRK_DOC(BIND_FUNC(module,execvp),
817 "@brief Replace the current process.\n"
818 "@arguments filename,args\n\n"
819 "The @c exec* family of functions replaces the calling process's image with a new one. "
820 "@c execvp takes a @p filename of a binary and a @ref list @p args of @ref str arguments to "
821 "pass to the new executable. @p filename will be searched for in @c $PATH.");
827 KRK_DOC(BIND_FUNC(module,access),
828 "@brief Determine if a file can be accessed.\n"
829 "@arguments path,mask\n\n"
830 "Use the values @c F_OK, @c R_OK, @c W_OK, and @c X_OK to construct @p mask and check if the current "
831 "process has sufficient access rights to perform the requested operations on the file "
835 KRK_DOC(BIND_FUNC(module,pipe),
836 "@brief Create a pipe.\n\n"
837 "Creates a _pipe_, returning a two-tuple of file descriptors for the read and write ends respectively.");
838 KRK_DOC(BIND_FUNC(module,kill),
839 "@brief Send a signal to a process.\n"
840 "@arguments pid,signum\n\n"
841 "Send the signal @p signum to the process at @p pid.\n");
842 KRK_DOC(BIND_FUNC(module,fork),
843 "@brief Fork the current process.\n\n"
844 "Returns the PID of the new child process in the original process and @c 0 in the child.");
845 KRK_DOC(BIND_FUNC(module,symlink),
846 "@brief Create a symbolic link.\n"
847 "@arguments src,dst\n\n"
848 "Creates a symbolic link at @p src pointing to @p dst.");
850 KRK_DOC(BIND_FUNC(module,tcgetpgrp),
851 "@brief Get the terminal foreground process group.\n"
853 "Return the PID representing the foreground process group of the terminal specified by the file descriptor @p fd.");
854 KRK_DOC(BIND_FUNC(module,tcsetpgrp),
855 "@brief %Set the terminal foreground process group.\n"
856 "@arguments fd,pgrp\n\n"
857 "%Set the PID representing the foreground process group of the terminal specified by the file descriptor @p fd to @p pgrp.");
858 KRK_DOC(BIND_FUNC(module,ttyname),
859 "@brief Get the path to a terminal device.\n"
861 "Returns a @ref str representing the path to the terminal device provided by the file descriptor @p fd.");
863 KRK_DOC(BIND_FUNC(module,get_terminal_size),
864 "@brief Obtain the size of the terminal window.\n"
866 "Obtain the size of the host terminal as a tuple of columns and lines.");
869 _loadEnviron(module);
872 KrkClass * stat_result =
krk_makeClass(module, &KRK_BASE_CLASS(stat_result),
"stat_result",
vm.baseClasses->objectClass);
873 BIND_METHOD(stat_result,__repr__);
876 KRK_DOC(BIND_FUNC(module,stat),
877 "@brief Get the status of a file\n"
878 "@arguments path\n\n"
879 "Runs the @c stat system call on @p path. Returns a @ref stat_result.\n");
886 "@brief Functions to check results from @ref stat calls.");
888 BIND_FUNC(module,S_ISBLK);
889 BIND_FUNC(module,S_ISCHR);
890 BIND_FUNC(module,S_ISDIR);
891 BIND_FUNC(module,S_ISFIFO);
892 BIND_FUNC(module,S_ISREG);
894 BIND_FUNC(module,S_ISLNK);
895 BIND_FUNC(module,S_ISSOCK);
KrkValue krk_runtimeError(KrkClass *type, const char *fmt,...)
Produce and raise an exception with a formatted message.
Struct definitions for core object types.
Immutable sequence of bytes.
size_t length
Length of data in bytes.
uint8_t * bytes
Pointer to separately-stored bytes data.
KrkBytes * krk_newBytes(size_t length, uint8_t *source)
Create a new byte array.
KrkClass * krk_makeClass(KrkInstance *module, KrkClass **_class, const char *name, KrkClass *base)
Convenience function for creating new types.
void krk_finalizeClass(KrkClass *_class)
Finalize a class by collecting pointers to core methods.
KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw)
Create a dict object.
KrkInstance * krk_newInstance(KrkClass *_class)
Create a new instance of the given class.
KrkTable fields
Attributes table.
The most basic object type.
Immutable sequence of Unicode codepoints.
KrkString * krk_copyString(const char *chars, size_t length)
Obtain a string object representation of the given C string.
char * chars
UTF8 canonical data.
size_t length
String length in bytes.
int krk_tableSet(KrkTable *table, KrkValue key, KrkValue value)
Assign a value to a key in a table.
void krk_attachNamedObject(KrkTable *table, const char name[], KrkObj *obj)
Attach an object to an attribute table.
void krk_attachNamedValue(KrkTable *table, const char name[], KrkValue obj)
Attach a value to an attribute table.
KrkTuple * krk_newTuple(size_t length)
Create a new tuple.
Stack reference or primative value.
Utilities for creating native bindings.
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
#define KRK_DOC(thing, text)
Attach documentation to a thing of various types.
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
#define vm
Convenience macro for namespacing.
void krk_module_init_os(void)
Initialize the built-in 'os' module.
KrkValue krk_pop(void)
Pop the top of the stack.
void krk_push(KrkValue value)
Push a stack value.
KrkValue krk_callDirect(KrkObj *callable, int argCount)
Call a closure or native function with argCount arguments.
KrkValue krk_peek(int distance)
Peek down from the top of the stack.