add sleep() function and improve Windows support

I could only test Windows support by compiling with gcc MinGW-w64 and
running with Wine.
This commit is contained in:
r4 2021-12-25 14:06:20 +01:00
parent dd67a1bf5d
commit b4c369e1d9
5 changed files with 46 additions and 6 deletions

View File

@ -1,6 +1,9 @@
CFLAGS = -ggdb -std=c11 -Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition ifneq ($(OS),Windows_NT)
#CFLAGS = -pg -std=c11 -Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition DEFS = -D_POSIX_C_SOURCE=200112L
#CFLAGS = -O3 -std=c11 -Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition 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 LDFLAGS = -lm
SOURCE = main.c util.c tok.c lex.c ir.c parse.c runtime.c vm.c map.c 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 HEADERS = util.h tok.h lex.h ir.h parse.h runtime.h vm.h map.h

11
main.c
View File

@ -4,6 +4,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#include "ir.h" #include "ir.h"
#include "lex.h" #include "lex.h"
@ -83,6 +84,15 @@ static Value fn_pow(Value *args) {
}; };
} }
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) { int main(int argc, const char **argv) {
/* parse arguments */ /* parse arguments */
size_t nargs = argc - 1; 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 = "int", .side_effects = false, .n_args = 1, .func = fn_int, },
{ .name = "float", .side_effects = false, .n_args = 1, .func = fn_float, }, { .name = "float", .side_effects = false, .n_args = 1, .func = fn_float, },
{ .name = "pow", .side_effects = false, .n_args = 2, .func = fn_pow, }, { .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])); IRToks ir = parse(&tokens, funcs, sizeof(funcs) / sizeof(funcs[0]));
if (err) { if (err) {

View File

@ -41,7 +41,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
} }
case IREq: case IREq:
case IRLt: case IRLt:
case IRLe: case IRLe: {
bool res; bool res;
if (lhs->type.kind == TypeInt && rhs->type.kind == TypeInt) { if (lhs->type.kind == TypeInt && rhs->type.kind == TypeInt) {
switch (instr) { switch (instr) {
@ -65,6 +65,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
.type.kind = TypeBool, .type.kind = TypeBool,
.Bool = res, .Bool = res,
}; };
}
case IRAnd: case IRAnd:
return (Value){ return (Value){
.type.kind = TypeBool, .type.kind = TypeBool,

17
util.c
View File

@ -2,6 +2,23 @@
#include <stdarg.h> #include <stdarg.h>
#ifdef WIN32
#include <windows.h> /* Sleep */
#else
#include <time.h> /* 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]; char errbuf[ERRSZ];
bool err; bool err;
size_t err_ln, err_col; size_t err_ln, err_col;

10
util.h
View File

@ -6,7 +6,13 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#ifdef WIN32
#include <windows.h> /* SSIZE_T */
typedef SSIZE_T ssize_t;
#else
#include <unistd.h> /* ssize_t */
#endif
typedef uint8_t pseudo_void; typedef uint8_t pseudo_void;
@ -29,6 +35,8 @@ typedef uint8_t pseudo_void;
#define C_RESET "\x1b[m" #define C_RESET "\x1b[m"
void sleep_secs(double secs);
#define ERRSZ 4096 #define ERRSZ 4096
extern char errbuf[ERRSZ]; extern char errbuf[ERRSZ];
extern bool err; extern bool err;