add more ffi types; add typedefs
authorMichael Wallner <mike@php.net>
Sun, 11 Oct 2015 12:45:50 +0000 (14:45 +0200)
committerMichael Wallner <mike@php.net>
Sun, 11 Oct 2015 12:45:50 +0000 (14:45 +0200)
idl/lexer.h
idl/lexer.re
idl/main.c
idl/parser.y
idl/types.h

index e3f7c5f2d350d9cbbbd439338e744cf267ed2339..62ce14b371e8d62cf7b6059443e1f98898f2ac26 100644 (file)
@@ -1,28 +1,26 @@
 #define BSIZE 256
 
 typedef int token_t;
-typedef unsigned char text;
+typedef char text;
 
 typedef struct PSI_Token {
        token_t type;
        unsigned line;
+       size_t size;
        text text[1];
 } PSI_Token;
 
-typedef struct impl impl;
-typedef struct decl decl;
+typedef struct impls impls;
+typedef struct decls decls;
+typedef struct decl_typedefs decl_typedefs;
 
 typedef struct PSI_Lexer {
        FILE *fp;
        char *fn;
-       struct {
-               size_t count;
-               decl **list;
-       } decl;
-       struct {
-               size_t count;
-               impl **list;
-       } impl;
+       char *lib;
+       decl_typedefs *defs;
+       decls *decls;
+       impls *impls;
        size_t line;
        text *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
 } PSI_Lexer;
index 3d1c660e82c61d260515a0620c60cd99afbf7a67..d52436ae361a146e0eefcb702ebdaedc36402a15 100644 (file)
 PSI_Token *PSI_TokenAlloc(PSI_Lexer *L, token_t t)
 {
        PSI_Token *T;
-       size_t token_len = L->cur - L->tok;
+       size_t token_len;
+
+       if (L->cur <= L->tok) {
+               return NULL;
+       }
+
+       token_len = L->cur - L->tok;
 
        T = malloc(sizeof(*T) + token_len);
        T->type = t;
        T->line = L->line;
+       T->size = token_len;
        T->text[token_len] = 0;
        memcpy(T->text, L->tok, token_len);
 
@@ -73,21 +80,17 @@ void PSI_LexerDtor(PSI_Lexer *L)
        if (L->fn) {
                free(L->fn);
        }
-       if (L->decl.list) {
-               size_t i;
-
-               for (i = 0; i < L->decl.count; ++i) {
-                       free_decl(L->decl.list[i]);
-               }
-               free(L->decl.list);
+       if (L->lib) {
+               free(L->lib);
        }
-       if (L->impl.list) {
-               size_t i;
-
-               for (i = 0; i < L->impl.count; ++i) {
-                       free_impl(L->impl.list[i]);
-               }
-               free(L->impl.list);
+       if (L->defs) {
+               free_decl_typedefs(L->defs);
+       }
+       if (L->decls) {
+               free_decls(L->decls);
+       }
+       if (L->impls) {
+               free_impls(L->impls);
        }
        memset(L, 0, sizeof(*L));
 }
@@ -141,7 +144,8 @@ token_t PSI_LexerScan(PSI_Lexer *L)
                B = [^a-zA-Z0-9_];
                W = [a-zA-Z0-9_];
                NAME = W+;
-               NSNAME = NAME ("\\" NAME)+;
+               NSNAME = (NAME)? ("\\" NAME)+;
+               QUOTED_STRING = "\"" ([^\"])+ "\"";
                NULL = 'NULL';
                MIXED = 'mixed';
                VOID = 'void';
@@ -151,9 +155,17 @@ token_t PSI_LexerScan(PSI_Lexer *L)
                DOUBLE = 'double';
                SINT8 = 'sint8';
                UINT8 = 'uint8';
+               SINT16 = 'sint16';
+               UINT16 = 'uint16';
+               SINT32 = 'sint32';
+               UINT32 = 'uint32';
+               SINT64 = 'sint64';
+               UINT64 = 'uint64';
                STRING = 'string';
                ARRAY = 'array';
                FUNCTION = 'function';
+               TYPEDEF = 'typedef';
+               LIB = 'lib';
                LET = 'let';
                SET = 'set';
                RET = 'ret';
@@ -172,8 +184,8 @@ token_t PSI_LexerScan(PSI_Lexer *L)
                ";" {return PSI_T_EOS;}
                "," {return PSI_T_COMMA;}
                ":" {return PSI_T_COLON;}
-               "{" {return PSI_T_LCURLY;}
-               "}" {return PSI_T_RCURLY;}
+               "{" {return PSI_T_LBRACE;}
+               "}" {return PSI_T_RBRACE;}
                "." {return PSI_T_DOT;}
                "=" {return PSI_T_EQUALS;}
                "$" {return PSI_T_DOLLAR;}
@@ -190,9 +202,17 @@ token_t PSI_LexerScan(PSI_Lexer *L)
                DOUBLE {return PSI_T_DOUBLE;}
                SINT8 {return PSI_T_SINT8;}
                UINT8 {return PSI_T_UINT8;}
+               SINT16 {return PSI_T_SINT16;}
+               UINT16 {return PSI_T_UINT16;}
+               SINT32 {return PSI_T_SINT32;}
+               UINT32 {return PSI_T_UINT32;}
+               SINT64 {return PSI_T_SINT64;}
+               UINT64 {return PSI_T_UINT64;}
                STRING {return PSI_T_STRING;}
                ARRAY {return PSI_T_ARRAY;}
                FUNCTION {return PSI_T_FUNCTION;}
+               TYPEDEF {return PSI_T_TYPEDEF;}
+               LIB {return PSI_T_LIB;}
                LET {return PSI_T_LET;}
                SET {return PSI_T_SET;}
                RET {return PSI_T_RET;}
@@ -205,8 +225,9 @@ token_t PSI_LexerScan(PSI_Lexer *L)
                TO_FLOAT {return PSI_T_TO_FLOAT;}
                TO_BOOL {return PSI_T_TO_BOOL;}
                [0-9] {return PSI_T_DIGIT;}
-               NSNAME {return PSI_T_NSNAME;}
                NAME {return PSI_T_NAME;}
+               NSNAME {return PSI_T_NSNAME;}
+               QUOTED_STRING {return PSI_T_QUOTED_STRING;}
                */
        }
        return -1;
index 6732b7dbac8b1a2b46b6e5f0861a35d1243b54cd..fe49647bf49b398229c3f48c3ac0aa19bd2ce2f8 100644 (file)
@@ -4,7 +4,7 @@
 #include "lexer.h"
 #include "parser.h"
 
-static volatile int TRACE;
+static int TRACE;
 
 static void loop(PSI_Lexer *L, void *P)
 {
@@ -16,12 +16,14 @@ static void loop(PSI_Lexer *L, void *P)
        }
 
        while (-1 != (t = PSI_LexerScan(L))) {
-               T = PSI_TokenAlloc(L, t);
+               if (!(T = PSI_TokenAlloc(L, t))) {
+                       break;
+               }
 
                if (TRACE) {
                        printf("# Token: <%s>(%d)\n", T->text, t);
                }
-               
+
                PSI_Parser(P, t, T, L);
        }
        PSI_Parser(P, 0, T, L);
index 74433f995ee35fff1625748bd5d0316ee2cc86ba..9d71e63560b7ac8e9009e8fd8c83cfd85db75a1b 100644 (file)
@@ -2,9 +2,22 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdarg.h>
 #include "lexer.h"
 #include "parser.h"
 #include "types.h"
+
+static void syntax_error(const char *fn, size_t ln, const char *msg, ...) {
+       fprintf(stderr, "WARNING: Syntax error on line %zu in '%s'%s", ln, fn, msg ? ": ": "\n");
+       if (msg) {
+               va_list argv;
+
+               va_start(argv, msg);
+               vfprintf(stderr, msg, argv);
+               va_end(argv);
+       }
+}
+
 }
 
 %name PSI_Parser
 %token_type {PSI_Token *}
 %token_destructor {free($$);}
 %extra_argument {PSI_Lexer *L}
+/* TOKEN is defined inside syntax_error */
 %syntax_error {
-       printf("ERROR: Syntax error on line %zu in '%s': '%s...'\n", L->line, L->fn, L->tok);
-       exit(1);
+       syntax_error(L->fn, L->line, "Unexpected token '%s'.\n", TOKEN->text);
 }
-
 file ::= blocks.
 
 blocks ::= block.
 blocks ::= blocks block.
 
-block ::= decl(decl_). {
-       L->decl.list = realloc(L->decl.list, ++L->decl.count * sizeof(*L->decl.list));
-       L->decl.list[L->decl.count-1] = decl_;
+block ::= COMMENT.
+
+block ::= LIB(T) QUOTED_STRING(libname) EOS. {
+       if (L->lib) {
+               syntax_error(L->fn, T->line, "Extra 'lib %s' statement has no effect.\n", libname->text);
+       } else {
+               L->lib = strndup(libname->text + 1, libname->size - 2);
+       }
+       free(libname);
+       free(T);
 }
-block ::= impl(impl_). {
-       L->impl.list = realloc(L->impl.list, ++L->impl.count * sizeof(*L->impl.list));
-       L->impl.list[L->impl.count-1] = impl_;
+
+block ::= decl(decl). {
+       L->decls = add_decl(L->decls, decl);
+}
+block ::= impl(impl). {
+       L->impls = add_impl(L->impls, impl);
+}
+block ::= decl_typedef(def). {
+       L->defs = add_decl_typedef(L->defs, def);
+}
+
+%type decl_typedef {decl_typedef*}
+decl_typedef(def) ::= TYPEDEF NAME(ALIAS) decl_type(type) EOS. {
+       def = init_decl_typedef(ALIAS->text, type);
+       free(ALIAS);
 }
-block ::= COMMENT.
 
 %type decl {decl*}
 decl(decl) ::= decl_arg(func) LPAREN decl_args(args) RPAREN EOS. {
@@ -92,9 +122,37 @@ decl_type(type_) ::= UINT8(T). {
        type_ = init_decl_type(T->type, T->text);
        free(T);
 }
+decl_type(type_) ::= SINT16(T). {
+       type_ = init_decl_type(T->type, T->text);
+       free(T);
+}
+decl_type(type_) ::= UINT16(T). {
+       type_ = init_decl_type(T->type, T->text);
+       free(T);
+}
+decl_type(type_) ::= SINT32(T). {
+       type_ = init_decl_type(T->type, T->text);
+       free(T);
+}
+decl_type(type_) ::= UINT32(T). {
+       type_ = init_decl_type(T->type, T->text);
+       free(T);
+}
+decl_type(type_) ::= SINT64(T). {
+       type_ = init_decl_type(T->type, T->text);
+       free(T);
+}
+decl_type(type_) ::= UINT64(T). {
+       type_ = init_decl_type(T->type, T->text);
+       free(T);
+}
+decl_type(type_) ::= NAME(T). {
+       type_ = init_decl_type(T->type, T->text);
+       free(T);
+}
 
 %type impl {impl*}
-impl(impl) ::= impl_func(func) LCURLY impl_stmts(stmts) RCURLY. {
+impl(impl) ::= impl_func(func) LBRACE impl_stmts(stmts) RBRACE. {
        impl = init_impl(func, stmts);
 }
 
@@ -103,6 +161,10 @@ impl_func(func) ::= FUNCTION NSNAME(NAME) LPAREN impl_args(args) RPAREN COLON im
        func = init_impl_func(NAME->text, args, type);
        free(NAME);
 }
+impl_func(func) ::= FUNCTION NSNAME(NAME) LPAREN RPAREN COLON impl_type(type). {
+       func = init_impl_func(NAME->text, NULL, type);
+       free(NAME);
+}
 
 %type impl_def_val {impl_def_val*}
 impl_def_val(def) ::= NULL. {
@@ -166,13 +228,14 @@ let_stmt(let) ::= LET decl_var(var) EQUALS let_value(val) EOS. {
 
 %type let_value {let_value*}
 let_value(val) ::= let_func(func) LPAREN impl_var(var) RPAREN. {
-       val = init_let_value(func, var);
+       val = init_let_value(func, var, 0);
 }
-let_value(val) ::= let_reference_null_pointer. {
-       val = init_let_value(NULL, NULL);
+let_value(val) ::= REFERENCE NULL. {
+       val = init_let_value(NULL, NULL, 1);
+}
+let_value(val) ::= NULL. {
+       val = init_let_value(NULL, NULL, 0);
 }
-
-let_reference_null_pointer ::= REFERENCE NULL.
 
 %type let_func {let_func*}
 let_func(func) ::= STRVAL(T). {
index b57f1db31588e9472a44a61de1309ef37264801a..c5b962eaf19df99b29927444aeb805909ac857bc 100644 (file)
@@ -7,7 +7,7 @@ typedef struct decl_type {
 static inline decl_type *init_decl_type(token_t type, text *name) {
        decl_type *t = malloc(sizeof(*t));
        t->type = type;
-       t->name = (text *) strdup((const char *) name);
+       t->name = strdup(name);
        return t;
 }
 
@@ -16,6 +16,48 @@ static inline void free_decl_type(decl_type *type) {
        free(type);
 }
 
+typedef struct decl_typedef {
+       char *alias;
+       decl_type *type;
+} decl_typedef;
+
+static inline decl_typedef *init_decl_typedef(text *name, decl_type *type) {
+       decl_typedef *t = malloc(sizeof(*t));
+       t->alias = strdup(name);
+       t->type = type;
+       return t;
+}
+
+static inline void free_decl_typedef(decl_typedef *t) {
+       free(t->alias);
+       free_decl_type(t->type);
+       free(t);
+}
+
+typedef struct decl_typedefs {
+       size_t count;
+       decl_typedef **list;
+} decl_typedefs;
+
+static decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_typedef *def) {
+       if (!defs) {
+               defs = calloc(1, sizeof(*defs));
+       }
+       defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list));
+       defs->list[defs->count-1] = def;
+       return defs;
+}
+
+static void free_decl_typedefs(decl_typedefs *defs) {
+       size_t i;
+
+       for (i = 0; i < defs->count; ++i) {
+               free_decl_typedef(defs->list[i]);
+       }
+       free(defs->list);
+       free(defs);
+}
+
 typedef struct decl_var {
        text *name;
        unsigned pointer_level;
@@ -127,6 +169,30 @@ static inline void free_decl(decl *d) {
        free(d);
 }
 
+typedef struct decls {
+       size_t count;
+       decl **list;
+} decls;
+
+static inline decls *add_decl(decls *decls, decl *decl) {
+       if (!decls) {
+               decls = calloc(1, sizeof(*decls));
+       }
+       decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list));
+       decls->list[decls->count-1] = decl;
+       return decls;
+}
+
+static inline void free_decls(decls *decls) {
+       size_t i;
+
+       for (i = 0; i < decls->count; ++i) {
+               free_decl(decls->list[i]);
+       }
+       free(decls->list);
+       free(decls);
+}
+
 typedef struct impl_type {
        text *name;
        token_t type;
@@ -212,9 +278,14 @@ typedef struct impl_args {
 
 static inline impl_args *init_impl_args(impl_arg *arg) {
        impl_args *args = malloc(sizeof(*args));
-       args->count = 1;
        args->args = malloc(sizeof(*args->args));
-       args->args[0] = arg;
+       if (arg) {
+               args->count = 1;
+               args->args[0] = arg;
+       } else {
+               args->count = 0;
+               args->args = NULL;
+       }
        return args;
 }
 
@@ -242,8 +313,8 @@ typedef struct impl_func {
 
 static inline impl_func *init_impl_func(text *name, impl_args *args, impl_type *type) {
        impl_func *func = malloc(sizeof(*func));
-       func->name = (text *) strdup((const char *) name);
-       func->args = args;
+       func->name = strdup(name);
+       func->args = args ? args : init_impl_args(NULL);
        func->return_type = type;
        return func;
 }
@@ -278,17 +349,11 @@ typedef struct let_value {
        unsigned null_pointer_ref:1;
 } let_value;
 
-static inline let_value *init_let_value(let_func *func, impl_var *var) {
+static inline let_value *init_let_value(let_func *func, impl_var *var, int null_pointer_ref) {
        let_value *val = malloc(sizeof(*val));
-
-       if (!func || !var) {
-               val->null_pointer_ref = 1;
-       } else {
-               val->null_pointer_ref = 0;
-       }
+       val->null_pointer_ref = null_pointer_ref;
        val->func = func;
        val->var = var;
-
        return val;
 }
 
@@ -469,3 +534,27 @@ static inline void free_impl(impl *impl) {
        free_impl_stmts(impl->stmts);
        free(impl);
 }
+
+typedef struct impls {
+       size_t count;
+       impl **list;
+} impls;
+
+static impls *add_impl(impls *impls, impl *impl) {
+       if (!impls) {
+               impls = calloc(1, sizeof(*impls));
+       }
+       impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list));
+       impls->list[impls->count-1] = impl;
+       return impls;
+}
+
+static void free_impls(impls *impls) {
+       size_t i;
+
+       for (i = 0; i < impls->count; ++i) {
+               free_impl(impls->list[i]);
+       }
+       free(impls->list);
+       free(impls);
+}