Removed textual UI representation
This commit is contained in:
parent
4f677d200e
commit
5d54d65894
65
demo/demo.c
65
demo/demo.c
@ -2793,68 +2793,6 @@ record_window(struct zr_context *ctx, struct zr_buffer *buffer)
|
||||
zr_recording_end(ctx);
|
||||
}
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* COMPILED WINDOW
|
||||
*
|
||||
* ===============================================================*/
|
||||
static void
|
||||
compile_log(void *userdata, zr_size line, const char *fmt, ...)
|
||||
{
|
||||
int l = (int)line;
|
||||
char buffer[1024];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
buffer[1023] = 0;
|
||||
fprintf(stderr, "[COMPILER] error (%d): %s\n", l, buffer);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void
|
||||
compile_window(struct zr_context *ctx, struct zr_buffer *buffer)
|
||||
{
|
||||
/* **EXPERIMENTAL** */
|
||||
const char script[] =
|
||||
"begin('Recorded', 420, 350, 200, 350, 317)"
|
||||
"layout_row_static(30, 150, 1)"
|
||||
"button_text(0, 'Test', 0)"
|
||||
"slider(1, 0, 5, 10, 1)"
|
||||
"progress(2, 20, 100, 1)"
|
||||
"property(3, 'Compression:', 0, 20, 100, 10, 1, 0);"
|
||||
"select(4, 'select me', 18, 0)"
|
||||
"check(5, 'check me', 1)"
|
||||
"layout_row_static(30, 50, 3)"
|
||||
"option(6, 'RGB', 1)"
|
||||
"option(8, 'HSV', 0)"
|
||||
"option(9, 'HEX', 0)"
|
||||
"layout_push(10, 1, 'Tab', 0)"
|
||||
"layout_row_static(30, 150, 1)"
|
||||
"button_text(11, 'Test', 0)"
|
||||
"layout_pop()"
|
||||
"end()";
|
||||
|
||||
enum zr_compiler_status ret;
|
||||
UNUSED(ctx);
|
||||
ret = zr_compile(buffer, script, sizeof(script), compile_log, 0);
|
||||
if (ret == ZR_COMPILER_OK) return;
|
||||
else if (ret == ZR_COMPILER_INVALID_VALUE)
|
||||
fprintf(stdout, "[Zahnrad]: compiling error: invalid valid\n");
|
||||
else if (ret == ZR_COMPILER_INVALID_ARG)
|
||||
fprintf(stdout, "[Zahnrad]: compiling error: invalid operation argument\n");
|
||||
else if (ret == ZR_COMPILER_OP_NOT_FOUND)
|
||||
fprintf(stdout, "[Zahnrad]: compiling error: invalid operation\n");
|
||||
else if (ret == ZR_COMPILER_MISSING_COMMA)
|
||||
fprintf(stdout, "[Zahnrad]: compiling error: missing comma between arguments\n");
|
||||
else if (ret == ZR_COMPILER_WRONG_ARG_TYPE)
|
||||
fprintf(stdout, "[Zahnrad]: compiling error: argument has wrong type\n");
|
||||
else if (ret == ZR_COMPILER_NO_MEMORY)
|
||||
fprintf(stdout, "[Zahnrad]: out of memory\n");
|
||||
else if (ret == ZR_COMPILER_INVALID_SCRIPT)
|
||||
fprintf(stdout, "[Zahnrad]: script is not correct\n");
|
||||
}
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* REPLAY WINDOW
|
||||
@ -3061,8 +2999,7 @@ run_demo(struct demo *gui)
|
||||
|
||||
memset(&nodedit, 0, sizeof(nodedit));
|
||||
zr_buffer_init_fixed(&record, record_memory, sizeof(record_memory));
|
||||
compile_window(ctx, &record);
|
||||
/*record_window(ctx, &record);*/
|
||||
record_window(ctx, &record);
|
||||
node_editor_init(&nodedit);
|
||||
#ifndef DEMO_DO_NOT_DRAW_IMAGES
|
||||
#ifdef __unix__
|
||||
|
611
zahnrad.c
611
zahnrad.c
@ -14190,617 +14190,6 @@ zr_store_op(struct zr_buffer *buffer, union zr_param *p, int count)
|
||||
}
|
||||
}
|
||||
|
||||
/* ==============================================================
|
||||
*
|
||||
* COMPILER
|
||||
*
|
||||
* =============================================================== */
|
||||
#define ZR_LEXER_DEFAULT_PUNCTION_MAP(PUNCTUATION)\
|
||||
PUNCTUATION(">>=", ZR_PUNCT_RSHIFT_ASSIGN)\
|
||||
PUNCTUATION("<<=", ZR_PUNCT_LSHIFT_ASSIGN)\
|
||||
PUNCTUATION("...", ZR_PUNCT_PARAMS)\
|
||||
PUNCTUATION("&&", ZR_PUNCT_LOGIC_AND)\
|
||||
PUNCTUATION("||", ZR_PUNCT_LOGIC_OR)\
|
||||
PUNCTUATION(">=", ZR_PUNCT_LOGIC_GEQ)\
|
||||
PUNCTUATION("<=", ZR_PUNCT_LOGIC_LEQ)\
|
||||
PUNCTUATION("==", ZR_PUNCT_LOGIC_EQ)\
|
||||
PUNCTUATION("!=", ZR_PUNCT_LOGIC_UNEQ)\
|
||||
PUNCTUATION("*=", ZR_PUNCT_MUL_ASSIGN)\
|
||||
PUNCTUATION("/=", ZR_PUNCT_DIV_ASSIGN)\
|
||||
PUNCTUATION("%=", ZR_PUNCT_MOD_ASSIGN)\
|
||||
PUNCTUATION("+=", ZR_PUNCT_ADD_ASSIGN)\
|
||||
PUNCTUATION("-=", ZR_PUNCT_SUB_ASSIGN)\
|
||||
PUNCTUATION("++", ZR_PUNCT_INC)\
|
||||
PUNCTUATION("--", ZR_PUNCT_DEC)\
|
||||
PUNCTUATION("&=", ZR_PUNCT_BIN_AND_ASSIGN)\
|
||||
PUNCTUATION("|=", ZR_PUNCT_BIN_OR_ASSIGN)\
|
||||
PUNCTUATION("^=", ZR_PUNCT_BIN_XOR_ASSIGN)\
|
||||
PUNCTUATION(">>", ZR_PUNCT_RSHIFT)\
|
||||
PUNCTUATION("<<", ZR_PUNCT_LSHIFT)\
|
||||
PUNCTUATION("->", ZR_PUNCT_POINTER)\
|
||||
PUNCTUATION("::", ZR_PUNCT_CPP1)\
|
||||
PUNCTUATION(".*", ZR_PUNCT_CPP2)\
|
||||
PUNCTUATION("*", ZR_PUNCT_MUL)\
|
||||
PUNCTUATION("/", ZR_PUNCT_DIV)\
|
||||
PUNCTUATION("%", ZR_PUNCT_MOD)\
|
||||
PUNCTUATION("+", ZR_PUNCT_ADD)\
|
||||
PUNCTUATION("-", ZR_PUNCT_SUB)\
|
||||
PUNCTUATION("=", ZR_PUNCT_ASSIGN)\
|
||||
PUNCTUATION("&", ZR_PUNCT_BIN_AND)\
|
||||
PUNCTUATION("|", ZR_PUNCT_BIN_OR)\
|
||||
PUNCTUATION("^", ZR_PUNCT_BIN_XOR)\
|
||||
PUNCTUATION("~", ZR_PUNCT_BIN_NOT)\
|
||||
PUNCTUATION("!", ZR_PUNCT_LOGIC_NOT)\
|
||||
PUNCTUATION(">", ZR_PUNCT_LOGIC_GREATER)\
|
||||
PUNCTUATION("<", ZR_PUNCT_LOGIC_LESS)\
|
||||
PUNCTUATION(".", ZR_PUNCT_REF)\
|
||||
PUNCTUATION(",", ZR_PUNCT_COMMA)\
|
||||
PUNCTUATION(";", ZR_PUNCT_SEMICOLON)\
|
||||
PUNCTUATION(":", ZR_PUNCT_COLON)\
|
||||
PUNCTUATION("?", ZR_PUNCT_QUESTIONMARK)\
|
||||
PUNCTUATION("(", ZR_PUNCT_PARENTHESE_OPEN)\
|
||||
PUNCTUATION(")", ZR_PUNCT_PARENTHESE_CLOSE)\
|
||||
PUNCTUATION("{", ZR_PUNCT_BRACE_OPEN)\
|
||||
PUNCTUATION("}", ZR_PUNCT_BRACE_CLOSE)\
|
||||
PUNCTUATION("[", ZR_PUNCT_BRACKET_OPEN)\
|
||||
PUNCTUATION("]", ZR_PUNCT_BRACKET_CLOSE)\
|
||||
PUNCTUATION("\\", ZR_PUNCT_BACKSLASH)\
|
||||
PUNCTUATION("#", ZR_PUNCT_PRECOMPILER)\
|
||||
PUNCTUATION("$", ZR_PUNCT_DOLLAR)
|
||||
|
||||
enum zr_lexer_default_punctuation_ids {
|
||||
#define PUNCTUATION(chars, id) id,
|
||||
ZR_LEXER_DEFAULT_PUNCTION_MAP(PUNCTUATION)
|
||||
#undef PUNCTUATION
|
||||
ZR_PUNCT_MAX
|
||||
};
|
||||
|
||||
static const struct zr_punctuation {
|
||||
const char *string; int id;
|
||||
} zr_lexer_default_punctuations[] = {
|
||||
#define PUNCTUATION(chars, id) {chars, id},
|
||||
ZR_LEXER_DEFAULT_PUNCTION_MAP(PUNCTUATION)
|
||||
#undef PUNCTUATION
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
enum zr_token_type {
|
||||
ZR_TOKEN_STRING,
|
||||
ZR_TOKEN_LITERAL,
|
||||
ZR_TOKEN_NUMBER,
|
||||
ZR_TOKEN_NAME,
|
||||
ZR_TOKEN_PUNCT
|
||||
};
|
||||
|
||||
struct zr_token {
|
||||
enum zr_token_type type;
|
||||
zr_size line;
|
||||
int line_crossed;
|
||||
struct {unsigned long i; double f;} value;
|
||||
const char *str;
|
||||
zr_size len;
|
||||
int punct;
|
||||
};
|
||||
|
||||
struct zr_lexer {
|
||||
const char *last;
|
||||
const char *current;
|
||||
const char *end;
|
||||
zr_size length;
|
||||
zr_size line;
|
||||
zr_size last_line;
|
||||
zr_compile_log_f log;
|
||||
void *userdata;
|
||||
int error;
|
||||
};
|
||||
|
||||
static int
|
||||
zr_skip_white_space(struct zr_lexer *lexer, int current_line)
|
||||
{
|
||||
while (1) {
|
||||
/* skip white spaces */
|
||||
while (*lexer->current <= ' ' && lexer->current < lexer->end) {
|
||||
if (!*lexer->current || lexer->current == lexer->end)
|
||||
return 0;
|
||||
if (*lexer->current == '\n') {
|
||||
lexer->line++;
|
||||
if (current_line) {
|
||||
lexer->current++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
lexer->current++;
|
||||
}
|
||||
|
||||
/* skip comments */
|
||||
if (*lexer->current == '/' && lexer->current < lexer->end) {
|
||||
if (lexer->current+1 >= lexer->end)
|
||||
return 0;
|
||||
|
||||
if (*(lexer->current + 1) == '/') {
|
||||
/* C++ style comments */
|
||||
lexer->current++;
|
||||
do {
|
||||
lexer->current++;
|
||||
if ((lexer->current >= lexer->end) || !*lexer->current)
|
||||
return 0;
|
||||
} while (*lexer->current != '\n');
|
||||
lexer->line++;
|
||||
lexer->current++;
|
||||
if (current_line)
|
||||
return 1;
|
||||
if (lexer->current >= lexer->end || !*lexer->current)
|
||||
return 0;
|
||||
continue;
|
||||
} else if ((*lexer->current + 1) == '*') {
|
||||
/* C style comments */
|
||||
lexer->current++;
|
||||
while (1) {
|
||||
lexer->current++;
|
||||
if (lexer->current >= lexer->end || !*lexer->current)
|
||||
return 0;
|
||||
if (*lexer->current == '\n') {
|
||||
lexer->line++;
|
||||
} else if (*lexer->current == '/' && lexer->current+1 < lexer->end) {
|
||||
if (*(lexer->current-1) == '*') break;
|
||||
if (*(lexer->current+1) == '*' && lexer->log) {
|
||||
lexer->log(lexer->userdata, lexer->line, "nested comment");
|
||||
}
|
||||
}
|
||||
}
|
||||
lexer->current++;
|
||||
if (lexer->current >= lexer->end || !*lexer->current)
|
||||
return 0;
|
||||
lexer->current++;
|
||||
if (lexer->current >= lexer->end || !*lexer->current)
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
zr_read_string(struct zr_lexer *lexer, struct zr_token *token, int quote)
|
||||
{
|
||||
zr_size tmpline;
|
||||
const char *tmp;
|
||||
|
||||
if (quote == '\"')
|
||||
token->type = ZR_TOKEN_STRING;
|
||||
else token->type = ZR_TOKEN_LITERAL;
|
||||
lexer->current++;
|
||||
if (lexer->current >= lexer->end)
|
||||
return 0;
|
||||
|
||||
token->len = 0;
|
||||
token->str = lexer->current;
|
||||
while (lexer->current < lexer->end) {
|
||||
if (*lexer->current == quote) {
|
||||
lexer->current++;
|
||||
if (lexer->current >= lexer->end)
|
||||
return 0;
|
||||
|
||||
tmp = lexer->current;
|
||||
tmpline = lexer->line;
|
||||
if (!zr_skip_white_space(lexer, 0)) {
|
||||
lexer->current = tmp;
|
||||
lexer->line = tmpline;
|
||||
break;
|
||||
}
|
||||
if (*lexer->current == '\0') {
|
||||
if (lexer->log)
|
||||
lexer->log(lexer->userdata, lexer->line,
|
||||
"expecting string after '\' terminated line");
|
||||
lexer->error = 1;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
if (*lexer->current == '\0') {
|
||||
if (lexer->log)
|
||||
lexer->log(lexer->userdata, lexer->line, "missing trailing quote");
|
||||
lexer->error = 1;
|
||||
return 0;
|
||||
}
|
||||
if (*lexer->current == '\n') {
|
||||
if (lexer->log)
|
||||
lexer->log(lexer->userdata, lexer->line, "newline inside string");
|
||||
lexer->error = 1;
|
||||
return 0;
|
||||
}
|
||||
lexer->current++;
|
||||
}
|
||||
}
|
||||
if (token->str)
|
||||
token->len = (zr_size)(lexer->current - token->str) - 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
zr_read_name(struct zr_lexer *lexer, struct zr_token *token)
|
||||
{
|
||||
char c;
|
||||
token->type = ZR_TOKEN_NAME;
|
||||
token->str = lexer->current;
|
||||
token->len = 0;
|
||||
do {
|
||||
token->len++;
|
||||
lexer->current++;
|
||||
if (lexer->current >= lexer->end)
|
||||
break;
|
||||
c = *lexer->current;
|
||||
} while ((c >= 'a' && c <= 'z') ||
|
||||
(c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') ||
|
||||
c == '_');
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
zr_read_number(struct zr_lexer *lexer, struct zr_token *token)
|
||||
{
|
||||
int dot;
|
||||
char c, c2;
|
||||
|
||||
token->type = ZR_TOKEN_NUMBER;
|
||||
token->value.f = 0;
|
||||
token->value.i = 0;
|
||||
token->str = 0;
|
||||
token->len = 0;
|
||||
|
||||
c = *lexer->current;
|
||||
if ((lexer->current + 1) < lexer->end)
|
||||
c2 = *(lexer->current + 1);
|
||||
else c2 = 0;
|
||||
|
||||
/* decimal or floating point number */
|
||||
dot = 0;
|
||||
token->str = lexer->current;
|
||||
while (1) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
} else if (c == '.') dot++;
|
||||
else break;
|
||||
token->len++;
|
||||
if (lexer->current+1 >= lexer->end) break;
|
||||
c = *(++lexer->current);
|
||||
}
|
||||
if (c == 'e' && dot == 0)
|
||||
dot++; /* scientific notation */
|
||||
if (dot) {
|
||||
if (c == 'e') {
|
||||
if (lexer->current+1 >= lexer->end)
|
||||
return 0;
|
||||
|
||||
token->len++;
|
||||
c = *(++lexer->current);
|
||||
if (c == '-' || c == '+') {
|
||||
token->len++;
|
||||
if (lexer->current+1 >= lexer->end)
|
||||
return 0;
|
||||
c = *(++lexer->current);
|
||||
}
|
||||
while (c >= '0' && c <= '9') {
|
||||
if (lexer->current+1 >= lexer->end) break;
|
||||
c = *(++lexer->current);
|
||||
token->len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
zr_read_punctuation(struct zr_lexer *lexer, struct zr_token *token)
|
||||
{
|
||||
int l, i;
|
||||
const char *p;
|
||||
const struct zr_punctuation *punc;
|
||||
|
||||
token->len = 0;
|
||||
token->str = lexer->current;
|
||||
for (i = 0; zr_lexer_default_punctuations[i].string; ++i) {
|
||||
punc = &zr_lexer_default_punctuations[i];
|
||||
p = punc->string;
|
||||
for (l = 0; p[l] && lexer->current < lexer->end && lexer->current[l]; ++l) {
|
||||
if (lexer->current[l] != p[l])
|
||||
break;
|
||||
}
|
||||
if (!p[l]) {
|
||||
token->len += (zr_size)l;
|
||||
lexer->current += l;
|
||||
token->type = ZR_TOKEN_PUNCT;
|
||||
token->punct = punc->id;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
zr_parse(struct zr_lexer *lexer, struct zr_token *token)
|
||||
{
|
||||
int c;
|
||||
if (!lexer->current) return 0;
|
||||
if (lexer->current >= lexer->end) return 0;
|
||||
if (lexer->error == 1) return 0;
|
||||
|
||||
zr_zero_struct(*token);
|
||||
lexer->last = lexer->current;
|
||||
lexer->last_line = lexer->line;
|
||||
lexer->error = 0;
|
||||
if (!zr_skip_white_space(lexer, 0))
|
||||
return 0;
|
||||
|
||||
token->line = lexer->line;
|
||||
token->line_crossed = (lexer->line - lexer->last_line) ? 1 : 0;
|
||||
|
||||
c = *lexer->current;
|
||||
if ((c >= '0' && c <= '9') ||
|
||||
(c == '.' && (*(lexer->current + 1)) >= '0' &&
|
||||
(c == '.' && (*(lexer->current + 1)) <= '9'))) {
|
||||
if (!zr_read_number(lexer, token)) return 0;
|
||||
} else if (c == '\"' || c == '\'') {
|
||||
if (!zr_read_string(lexer, token, c)) return 0;
|
||||
} else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') {
|
||||
if (!zr_read_name(lexer, token)) return 0;
|
||||
} else if (!zr_read_punctuation(lexer, token)) {
|
||||
if (lexer->log)
|
||||
lexer->log(lexer->userdata, lexer->line, "unkown punctuation");
|
||||
lexer->error = 1;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
zr_check_type(struct zr_lexer *lexer, enum zr_token_type type,
|
||||
int subtype, struct zr_token *token)
|
||||
{
|
||||
struct zr_token tok;
|
||||
if (!zr_parse(lexer, &tok))
|
||||
return 0;
|
||||
if (tok.type == type && (tok.punct == subtype)) {
|
||||
*token = tok;
|
||||
return 1;
|
||||
}
|
||||
/* unread token */
|
||||
lexer->current = lexer->last;
|
||||
lexer->line = lexer->last_line;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double
|
||||
zr_token_parse_number(const char *p, zr_size length)
|
||||
{
|
||||
int i, div, pow;
|
||||
double m;
|
||||
zr_size len = 0;
|
||||
double f = 0;
|
||||
while (len < length && p[len] != '.' && p[len] != 'e') {
|
||||
f = f * 10.0 + (double)(p[len] - '0');
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len < length && p[len] == '.') {
|
||||
len++;
|
||||
for (m = 0.1; len < length; len++) {
|
||||
f = f + (double)(p[len] - '0') * m;
|
||||
m *= 0.1;
|
||||
}
|
||||
}
|
||||
if (len < length && p[len] == 'e' ) {
|
||||
len++;
|
||||
if (p[len] == '-') {
|
||||
div = 1;
|
||||
len++;
|
||||
} else if (p[len] == '+') {
|
||||
div = 0;
|
||||
len++;
|
||||
} else div = 0;
|
||||
pow = 0;
|
||||
for (pow = 0; len < length; len++)
|
||||
pow = pow * 10 + (int)(p[len] - '0');
|
||||
for (m = 1.0, i = 0; i < pow; ++i)
|
||||
m *= 100.0;
|
||||
if (div) f /= m;
|
||||
else f *= m;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
enum zr_compiler_status
|
||||
zr_compile(struct zr_buffer *program, const char *script,
|
||||
zr_size len, zr_compile_log_f log, void *userdata)
|
||||
{
|
||||
unsigned short opcode;
|
||||
zr_size i = 0;
|
||||
struct zr_lexer lexer;
|
||||
|
||||
ZR_ASSERT(program);
|
||||
ZR_ASSERT(script);
|
||||
if (!program || !script)
|
||||
return ZR_COMPILER_INVALID_VALUE;
|
||||
|
||||
/* setup lexer */
|
||||
zr_zero_struct(lexer);
|
||||
lexer.error = 0;
|
||||
lexer.current = script;
|
||||
lexer.end = script + len;
|
||||
lexer.length = len;
|
||||
lexer.line = 0;
|
||||
lexer.log = log;
|
||||
lexer.userdata = userdata;
|
||||
|
||||
while (!lexer.error && *lexer.current && lexer.current < lexer.end) {
|
||||
struct zr_token tok;
|
||||
struct zr_token name;
|
||||
char buffer[1024];
|
||||
|
||||
/* parse function name */
|
||||
if (!zr_parse(&lexer, &name) || name.type != ZR_TOKEN_NAME) {
|
||||
if (!lexer.current || !(lexer.current < lexer.end))
|
||||
break;
|
||||
ZR_ASSERT(!ZR_COMPILER_INVALID_SCRIPT);
|
||||
return ZR_COMPILER_INVALID_SCRIPT;
|
||||
}
|
||||
if (!zr_check_type(&lexer, ZR_TOKEN_PUNCT, ZR_PUNCT_PARENTHESE_OPEN, &tok)) {
|
||||
ZR_ASSERT(!ZR_COMPILER_INVALID_SCRIPT);
|
||||
return ZR_COMPILER_INVALID_SCRIPT;
|
||||
}
|
||||
|
||||
/* try to find instruction */
|
||||
for (opcode = 0; opcode < ZR_OP_MAX; ++opcode) {
|
||||
if (!zr_stricmpn(zr_op_table[opcode].keyword, name.str, (int)name.len))
|
||||
break;
|
||||
}
|
||||
if (opcode == ZR_OP_MAX) {
|
||||
ZR_ASSERT(!ZR_COMPILER_OP_NOT_FOUND);
|
||||
return ZR_COMPILER_OP_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* parse widget arguments */
|
||||
{union zr_param p[32];
|
||||
const struct zr_instruction *op = &zr_op_table[opcode];
|
||||
ZR_ASSERT(op->argc < ZR_LEN(p));
|
||||
if (op->argc >= ZR_LEN(p)) {
|
||||
ZR_ASSERT(!ZR_COMPILER_WRONG_ARG_COUNT);
|
||||
return ZR_COMPILER_WRONG_ARG_COUNT;
|
||||
}
|
||||
|
||||
for (i = 0; i < op->argc; ++i)
|
||||
{
|
||||
double value;
|
||||
int has_comma = 1;
|
||||
if (op->fmt[i] != ZR_TYPE_PTR && op->fmt[i] != ZR_TYPE_IMAGE && op->fmt[i] != ZR_TYPE_OP) {
|
||||
if (!zr_parse(&lexer, &tok)) {
|
||||
if (log) log(userdata, lexer.line, "missing argument in %.*s at index %d", name.len, name.str, i+1);
|
||||
ZR_ASSERT(!ZR_COMPILER_INVALID_SCRIPT);
|
||||
return ZR_COMPILER_INVALID_SCRIPT;
|
||||
}
|
||||
}
|
||||
|
||||
switch (op->fmt[i]) {
|
||||
case ZR_TYPE_OP: {
|
||||
p[i].h.op = opcode;
|
||||
p[i].h.next = zr_op_table[opcode].argc;
|
||||
has_comma = 0;
|
||||
} break;
|
||||
|
||||
case ZR_TYPE_INT: {
|
||||
if (tok.type != ZR_TOKEN_NUMBER) {
|
||||
if (log) log(userdata, lexer.line, "argument in %.*s at index %d is not a number", name.len, name.str, i+1);
|
||||
ZR_ASSERT(!ZR_COMPILER_WRONG_ARG_TYPE);
|
||||
return ZR_COMPILER_WRONG_ARG_TYPE;
|
||||
}
|
||||
value = zr_token_parse_number(tok.str, tok.len);
|
||||
p[i].i = (int)value;
|
||||
} break;
|
||||
|
||||
case ZR_TYPE_UINT: {
|
||||
if (tok.type != ZR_TOKEN_NUMBER) {
|
||||
if (log) log(userdata, lexer.line, "argument in %.*s at index %d is not a number", name.len, name.str, i+1);
|
||||
ZR_ASSERT(!ZR_COMPILER_WRONG_ARG_TYPE);
|
||||
return ZR_COMPILER_WRONG_ARG_TYPE;
|
||||
}
|
||||
value = zr_token_parse_number(tok.str, tok.len);
|
||||
if (value < 0) value = 0;
|
||||
p[i].ui = (unsigned int)value;
|
||||
} break;
|
||||
|
||||
case ZR_TYPE_FLOAT: {
|
||||
if (tok.type != ZR_TOKEN_NUMBER) {
|
||||
if (log) log(userdata, lexer.line, "argument in %.*s at index %d is not a number", name.len, name.str, i+1);
|
||||
ZR_ASSERT(!ZR_COMPILER_WRONG_ARG_TYPE);
|
||||
return ZR_COMPILER_WRONG_ARG_TYPE;
|
||||
}
|
||||
value = zr_token_parse_number(tok.str, tok.len);
|
||||
p[i].f = (float)value;
|
||||
} break;
|
||||
|
||||
case ZR_TYPE_HASH: {
|
||||
if (tok.type == ZR_TOKEN_NUMBER) {
|
||||
value = zr_token_parse_number(tok.str, tok.len);
|
||||
if (value < 0) value = 0;
|
||||
p[i].hash = (zr_hash)value;
|
||||
} else if (tok.type == ZR_TOKEN_STRING || tok.type == ZR_TOKEN_LITERAL) {
|
||||
p[i].hash = zr_murmur_hash(tok.str, (int)tok.len, 0);
|
||||
} else {
|
||||
if (log) log(userdata, lexer.line, "argument in %.*s at index %d is not a number or string", name.len, name.str, i+1);
|
||||
ZR_ASSERT(!ZR_COMPILER_WRONG_ARG_TYPE);
|
||||
return ZR_COMPILER_WRONG_ARG_TYPE;
|
||||
}
|
||||
} break;
|
||||
|
||||
case ZR_TYPE_FLAGS: {
|
||||
if (tok.type != ZR_TOKEN_NUMBER) {
|
||||
if (log) log(userdata, lexer.line, "argument in %.*s at index %d is not a number", name.len, name.str, i+1);
|
||||
ZR_ASSERT(!ZR_COMPILER_WRONG_ARG_TYPE);
|
||||
return ZR_COMPILER_WRONG_ARG_TYPE;
|
||||
}
|
||||
value = zr_token_parse_number(tok.str, tok.len);
|
||||
if (value < 0) value = 0;
|
||||
p[i].flags = (zr_flags)value;
|
||||
} break;
|
||||
|
||||
case ZR_TYPE_CHEAT: {
|
||||
zr_size length = ZR_MIN(tok.len, ZR_LEN(buffer)-1);
|
||||
if (tok.type != ZR_TOKEN_STRING && tok.type != ZR_TOKEN_LITERAL) {
|
||||
if (log) log(userdata, lexer.line, "argument in %.*s at index %d is not a string", name.len, name.str, i+1);
|
||||
ZR_ASSERT(!ZR_COMPILER_WRONG_ARG_TYPE);
|
||||
return ZR_COMPILER_WRONG_ARG_TYPE;
|
||||
}
|
||||
|
||||
zr_memcopy(buffer, tok.str, length);
|
||||
buffer[length] = '\0';
|
||||
p[i].cheat = buffer;
|
||||
} break;
|
||||
|
||||
case ZR_TYPE_COLOR: {
|
||||
char hex_color[16];
|
||||
zr_size length = ZR_MIN(tok.len, ZR_LEN(hex_color)-1);
|
||||
if (tok.type != ZR_TOKEN_STRING && tok.type != ZR_TOKEN_LITERAL) {
|
||||
if (log) log(userdata, lexer.line, "argument in %.*s at index %d is not a hex color string", name.len, name.str, i+1);
|
||||
ZR_ASSERT(!ZR_COMPILER_WRONG_ARG_TYPE);
|
||||
return ZR_COMPILER_WRONG_ARG_TYPE;
|
||||
}
|
||||
|
||||
zr_memcopy(hex_color, tok.str, length);
|
||||
hex_color[length] = '\0';
|
||||
p[i].color = zr_rgba_hex(hex_color);
|
||||
} break;
|
||||
case ZR_TYPE_IMAGE: p[i].img.ptr = 0; has_comma = 0; break;
|
||||
case ZR_TYPE_PTR: p[i].ptr = 0; has_comma = 0; break;
|
||||
default:
|
||||
ZR_ASSERT(!ZR_COMPILER_INVALID_ARG);
|
||||
return ZR_COMPILER_INVALID_ARG;
|
||||
}
|
||||
if (has_comma && (int)i < op->argc-1 && !zr_check_type(&lexer, ZR_TOKEN_PUNCT, ZR_PUNCT_COMMA, &tok)) {
|
||||
if (log) log(userdata, lexer.line, "missing argument or ',' in %.*s after argument %d", name.len, name.str, i+1);
|
||||
ZR_ASSERT(!ZR_COMPILER_MISSING_COMMA);
|
||||
return ZR_COMPILER_MISSING_COMMA;
|
||||
}
|
||||
|
||||
}
|
||||
/* parse ')' at end of line */
|
||||
if (!zr_check_type(&lexer, ZR_TOKEN_PUNCT, ZR_PUNCT_PARENTHESE_CLOSE, &tok)) {
|
||||
if (log) log(userdata, lexer.line, "expected ')' at the end of widget: %.*s", name.len, name.str);
|
||||
ZR_ASSERT(!ZR_COMPILER_INVALID_ARG);
|
||||
return ZR_COMPILER_INVALID_ARG;
|
||||
}
|
||||
zr_check_type(&lexer, ZR_TOKEN_PUNCT, ZR_PUNCT_SEMICOLON, &tok);
|
||||
zr_store_op(program, p, op->argc);}
|
||||
}
|
||||
|
||||
{union zr_param p;
|
||||
p.h.op = ZR_OP_list_end;
|
||||
p.h.next = zr_op_table[p.h.op].argc;
|
||||
zr_store_op(program, &p, 1);}
|
||||
return ZR_COMPILER_OK;
|
||||
}
|
||||
|
||||
/* ==============================================================
|
||||
*
|
||||
* INTERPRETER
|
||||
|
16
zahnrad.h
16
zahnrad.h
@ -1727,22 +1727,6 @@ void zr_set_user_data(struct zr_context*, zr_handle handle);
|
||||
void zr_recording_begin(struct zr_context*, struct zr_buffer*);
|
||||
void zr_recording_end(struct zr_context*);
|
||||
|
||||
/* generate UI bytecode from script */
|
||||
enum zr_compiler_status {
|
||||
ZR_COMPILER_OK,
|
||||
ZR_COMPILER_INVALID_VALUE,
|
||||
ZR_COMPILER_INVALID_ARG,
|
||||
ZR_COMPILER_OP_NOT_FOUND,
|
||||
ZR_COMPILER_MISSING_COMMA,
|
||||
ZR_COMPILER_WRONG_ARG_TYPE,
|
||||
ZR_COMPILER_NO_MEMORY,
|
||||
ZR_COMPILER_WRONG_ARG_COUNT,
|
||||
ZR_COMPILER_INVALID_SCRIPT
|
||||
};
|
||||
typedef void(*zr_compile_log_f)(void *userdata, zr_size line, const char *error, ...);
|
||||
enum zr_compiler_status zr_compile(struct zr_buffer *program, const char *script,
|
||||
zr_size len, zr_compile_log_f, void *log_usr);
|
||||
|
||||
/* run recorded or compiled UI bytecode */
|
||||
int zr_exec(struct zr_context*, struct zr_buffer *event_buffer,
|
||||
int *event_count, const struct zr_event_mask*,
|
||||
|
Loading…
Reference in New Issue
Block a user