diff --git a/Makefile b/Makefile index 00ac8fc..6164d5b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,9 @@ -CFLAGS = -ggdb -std=c11 -Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -#CFLAGS = -pg -std=c11 -Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -#CFLAGS = -O3 -std=c11 -Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition +ifneq ($(OS),Windows_NT) + DEFS = -D_POSIX_C_SOURCE=200112L +endif +CFLAGS = $(DEFS) -ggdb -std=c11 -Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition +#CFLAGS = $(DEFS) -pg -std=c11 -Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition +#CFLAGS = $(DEFS) -O3 -std=c11 -Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition LDFLAGS = -lm SOURCE = main.c util.c tok.c lex.c ir.c parse.c runtime.c vm.c map.c HEADERS = util.h tok.h lex.h ir.h parse.h runtime.h vm.h map.h diff --git a/main.c b/main.c index 8b196a2..7821136 100644 --- a/main.c +++ b/main.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "ir.h" #include "lex.h" @@ -77,12 +78,21 @@ static Value fn_pow(Value *args) { set_err("pow() requires arguments of type float"); return (Value){0}; } - return (Value) { + return (Value){ .type.kind = TypeFloat, .Float = pow(args[0].Float, args[1].Float), }; } +static Value fn_sleep(Value *args) { + if (!(args[0].type.kind == TypeFloat && args[0].Float >= 0.0)) { + set_err("sleep() requires a positive float"); + return (Value){0}; + } + sleep_secs(args[0].Float); + return (Value){0}; +} + int main(int argc, const char **argv) { /* parse arguments */ size_t nargs = argc - 1; @@ -147,6 +157,7 @@ int main(int argc, const char **argv) { { .name = "int", .side_effects = false, .n_args = 1, .func = fn_int, }, { .name = "float", .side_effects = false, .n_args = 1, .func = fn_float, }, { .name = "pow", .side_effects = false, .n_args = 2, .func = fn_pow, }, + { .name = "sleep", .side_effects = true, .n_args = 1, .func = fn_sleep, }, }; IRToks ir = parse(&tokens, funcs, sizeof(funcs) / sizeof(funcs[0])); if (err) { diff --git a/runtime.c b/runtime.c index 2cf2d1f..8c6d8a3 100644 --- a/runtime.c +++ b/runtime.c @@ -41,7 +41,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) { } case IREq: case IRLt: - case IRLe: + case IRLe: { bool res; if (lhs->type.kind == TypeInt && rhs->type.kind == TypeInt) { switch (instr) { @@ -65,6 +65,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) { .type.kind = TypeBool, .Bool = res, }; + } case IRAnd: return (Value){ .type.kind = TypeBool, diff --git a/util.c b/util.c index b16242b..cc7cd8e 100644 --- a/util.c +++ b/util.c @@ -2,6 +2,23 @@ #include +#ifdef WIN32 +#include /* Sleep */ +#else +#include /* nanosleep */ +#endif + +void sleep_secs(double secs) { +#ifdef WIN32 + Sleep(secs * 1000.0); +#else + struct timespec ts; + ts.tv_sec = (time_t)secs; + ts.tv_nsec = (secs - (double)ts.tv_sec) * 1000000000.0; + nanosleep(&ts, NULL); +#endif +} + char errbuf[ERRSZ]; bool err; size_t err_ln, err_col; diff --git a/util.h b/util.h index 680d48f..195334b 100644 --- a/util.h +++ b/util.h @@ -6,7 +6,13 @@ #include #include #include -#include + +#ifdef WIN32 +#include /* SSIZE_T */ +typedef SSIZE_T ssize_t; +#else +#include /* ssize_t */ +#endif typedef uint8_t pseudo_void; @@ -29,6 +35,8 @@ typedef uint8_t pseudo_void; #define C_RESET "\x1b[m" +void sleep_secs(double secs); + #define ERRSZ 4096 extern char errbuf[ERRSZ]; extern bool err;