summaryrefslogtreecommitdiffhomepage
path: root/ast.h
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-12-23 20:54:05 +0100
committerJo-Philipp Wich <jo@mein.io>2021-02-17 14:10:51 +0100
commit3756806674da909ec6dc10ad25862b592792604e (patch)
treef2af7e47f8444caaff0a5a33599f381889db24e3 /ast.h
parent77580a893283f2bde7ab46496bd3a3d7b2fc6784 (diff)
treewide: rewrite ucode interpreter
Replace the former AST walking interpreter implementation with a single pass bytecode compiler and a corresponding virtual machine. The rewrite lays the groundwork for a couple of improvements with will be subsequently implemented: - Ability to precompile ucode sources into binary byte code - Strippable debug information - Reduced runtime memory usage Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'ast.h')
-rw-r--r--ast.h359
1 files changed, 0 insertions, 359 deletions
diff --git a/ast.h b/ast.h
deleted file mode 100644
index ecc67b3..0000000
--- a/ast.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2020 Jo-Philipp Wich <jo@mein.io>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __AST_H_
-#define __AST_H_
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdarg.h>
-#include <string.h>
-
-#ifdef JSONC
- #include <json.h>
-#else
- #include <json-c/json.h>
-#endif
-
-#define ALIGN(x) (((x) + sizeof(size_t) - 1) & -sizeof(size_t))
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#endif
-
-#define JSON_C_TO_STRING_STRICT (1<<31)
-
-enum uc_lex_state {
- UT_LEX_IDENTIFY_BLOCK,
- UT_LEX_BLOCK_COMMENT_START,
- UT_LEX_BLOCK_EXPRESSION_START,
- UT_LEX_BLOCK_EXPRESSION_EMIT_TAG,
- UT_LEX_BLOCK_STATEMENT_START,
- UT_LEX_BLOCK_COMMENT,
- UT_LEX_IDENTIFY_TOKEN,
- UT_LEX_PARSE_TOKEN,
- UT_LEX_EOF
-};
-
-struct uc_op {
- uint16_t type;
- uint16_t is_first:1;
- uint16_t is_op:1;
- uint16_t is_overflow:1;
- uint16_t is_postfix:1;
- uint16_t is_for_in:1;
- uint16_t is_list:1;
- uint16_t is_reg_icase:1;
- uint16_t is_reg_newline:1;
- uint16_t is_reg_global:1;
- uint16_t is_ellip:1;
- uint16_t is_arrow:1;
- uint32_t off;
- struct json_object *val;
- union {
- struct {
- struct json_object *proto;
- size_t type;
- void *data;
- uint32_t off;
- } tag;
- struct {
- uint32_t next;
- uint32_t operand[4];
- } tree;
- };
-};
-
-struct uc_scope {
- struct uc_scope *next;
- struct json_object *scope, *parent;
- size_t refs;
-};
-
-struct uc_source {
- struct uc_source *next;
- char *filename;
- uint32_t off;
- FILE *fp;
-};
-
-struct uc_function {
- char *name;
- union {
- struct json_object *args;
- void *cfn;
- };
- struct uc_scope *parent_scope;
- struct uc_source *source;
- uint32_t entry;
-};
-
-struct uc_callstack {
- struct uc_callstack *next;
- struct uc_function *function;
- struct uc_scope *scope;
- struct json_object *ctx;
- uint32_t off;
-};
-
-struct uc_state {
- struct uc_op *pool;
- uint32_t poolsize;
- uint32_t main;
- uint8_t srand_called:1;
- uint8_t trim_blocks:1;
- uint8_t lstrip_blocks:1;
- uint8_t strict_declarations:1;
- struct {
- enum uc_lex_state state;
- uint8_t eof:1;
- uint8_t skip_leading_whitespace:1;
- uint8_t skip_leading_newline:1;
- uint8_t within_expression_block:1;
- uint8_t within_statement_block:1;
- uint8_t semicolon_emitted:1;
- uint8_t expect_div:1;
- uint8_t is_escape:1;
- size_t buflen;
- char *buf, *bufstart, *bufend;
- size_t lookbehindlen;
- char *lookbehind;
- const void *tok;
- char esc[5];
- uint8_t esclen;
- int lead_surrogate;
- size_t lastoff;
- } lex;
- struct json_object *ctx, *rval, *exception;
- struct uc_scope *scopelist, *scope;
- struct uc_source *sources, *source;
- struct uc_callstack *callstack;
- struct uc_function *function;
- size_t calldepth;
-};
-
-struct uc_extended_type {
- const char *name;
- struct json_object *proto;
- void (*free)(void *);
-};
-
-static inline bool uc_is_type(struct json_object *val, int type) {
- struct uc_op *tag = json_object_get_userdata(val);
-
- return (tag && tag->type == type);
-};
-
-#define OP(idx) (&state->pool[idx])
-#define OP_POS(idx) OP(idx)->off
-#define OP_VAL(idx) OP(idx)->val
-#define OP_TYPE(idx) OP(idx)->type
-#define OP_NEXT(idx) OP(idx)->tree.next
-#define OP_IS_LIST(idx) OP(idx)->is_list
-#define OP_IS_ELLIP(idx) OP(idx)->is_ellip
-#define OP_IS_FOR_IN(idx) OP(idx)->is_for_in
-#define OP_IS_POSTFIX(idx) OP(idx)->is_postfix
-
-#define OPn_NUM ARRAY_SIZE(((struct uc_op *)NULL)->tree.operand)
-#define OPn(idx, n) OP(idx)->tree.operand[n]
-#define OPn_POS(idx, n) OP(OPn(idx, n))->off
-#define OPn_VAL(idx, n) OP(OPn(idx, n))->val
-#define OPn_TYPE(idx, n) OP(OPn(idx, n))->type
-#define OPn_IS_LIST(idx, n) OP(OPn(idx, n))->is_list
-#define OPn_IS_OVERFLOW(idx, n) OP(OPn(idx, n))->is_overflow
-
-
-
-uint32_t uc_new_op(struct uc_state *s, int type, struct json_object *val, ...);
-uint32_t uc_wrap_op(struct uc_state *s, uint32_t parent, ...);
-uint32_t uc_append_op(struct uc_state *s, uint32_t a, uint32_t b);
-struct json_object *uc_parse(struct uc_state *s, FILE *fp);
-void uc_free(struct uc_state *s);
-
-struct json_object *uc_new_func(struct uc_state *s, uint32_t decl, struct uc_scope *scope);
-struct json_object *uc_new_object(struct json_object *proto);
-struct json_object *uc_new_double(double v);
-struct json_object *uc_new_null(void);
-struct json_object *uc_new_regexp(const char *source, bool icase, bool newline, bool global, char **err);
-
-__attribute__((format(printf, 3, 0)))
-struct json_object *uc_new_exception(struct uc_state *s, uint32_t off, const char *fmt, ...);
-
-struct uc_scope *uc_new_scope(struct uc_state *s, struct uc_scope *parent);
-struct uc_scope *uc_parent_scope(struct uc_scope *scope);
-struct uc_scope *uc_acquire_scope(struct uc_scope *scope);
-void uc_release_scope(struct uc_scope *scope);
-
-bool uc_register_extended_type(const char *name, struct json_object *proto, void (*freefn)(void *));
-struct json_object *uc_set_extended_type(struct json_object *v, const char *name, void *data);
-void **uc_get_extended_type(struct json_object *val, const char *name);
-
-void *ParseAlloc(void *(*mfunc)(size_t));
-void Parse(void *pParser, int type, uint32_t off, struct uc_state *s);
-void ParseFree(void *pParser, void (*ffunc)(void *));
-
-
-static inline uint32_t getrefcnt(struct json_object *v) {
- struct {
- enum json_type o_type;
- uint32_t _ref_count;
- } *spy = (void *)v;
-
- return spy ? spy->_ref_count : 0;
-}
-
-static inline void *xalloc(size_t size) {
- void *ptr = calloc(1, size);
-
- if (!ptr) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return ptr;
-}
-
-static inline void *xrealloc(void *ptr, size_t size) {
- ptr = realloc(ptr, size);
-
- if (!ptr) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return ptr;
-}
-
-static inline char *xstrdup(const char *s) {
- char *ptr = strdup(s);
-
- if (!ptr) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return ptr;
-}
-
-static inline struct json_object *xjs_new_object(void) {
- struct json_object *ptr = json_object_new_object();
-
- if (!ptr) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return ptr;
-}
-
-static inline struct json_object *xjs_new_array(void) {
- struct json_object *ptr = json_object_new_array();
-
- if (!ptr) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return ptr;
-}
-
-static inline struct json_object *xjs_new_int64(int64_t n) {
- struct json_object *ptr = json_object_new_int64(n);
-
- if (!ptr) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return ptr;
-}
-
-static inline struct json_object *xjs_new_string(const char *s) {
- struct json_object *ptr = json_object_new_string(s);
-
- if (!ptr) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return ptr;
-}
-
-static inline struct json_object *xjs_new_string_len(const char *s, size_t len) {
- struct json_object *ptr = json_object_new_string_len(s, len);
-
- if (!ptr) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return ptr;
-}
-
-static inline struct json_object *xjs_new_boolean(bool v) {
- struct json_object *ptr = json_object_new_boolean(v);
-
- if (!ptr) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return ptr;
-}
-
-
-static inline struct json_tokener *xjs_new_tokener(void) {
- struct json_tokener *tok = json_tokener_new();
-
- if (!tok) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return tok;
-}
-
-static inline int xasprintf(char **strp, const char *fmt, ...) {
- va_list ap;
- int len;
-
- va_start(ap, fmt);
- len = vasprintf(strp, fmt, ap);
- va_end(ap);
-
- if (len == -1) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return len;
-}
-
-static inline int xvasprintf(char **strp, const char *fmt, va_list ap) {
- int len = vasprintf(strp, fmt, ap);
-
- if (len == -1) {
- fprintf(stderr, "Out of memory\n");
- abort();
- }
-
- return len;
-}
-
-#endif /* __AST_H_ */