Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5b4b719 authored by Tao Bao's avatar Tao Bao Committed by Gerrit Code Review
Browse files

Merge "edify: Some clean-ups to libedify."

parents 19bb05df 39119ad8
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
edify
=====

Update scripts (from donut onwards) are written in a new little
scripting language ("edify") that is superficially somewhat similar to
the old one ("amend").  This is a brief overview of the new language.
+0 −1
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ static void ExprDump(int depth, const Expr* n, const std::string& script) {

int main(int argc, char** argv) {
    RegisterBuiltins();
    FinishRegistration();

    if (argc != 2) {
        printf("Usage: %s <edify script>\n", argv[0]);
+13 −52
Original line number Diff line number Diff line
@@ -14,20 +14,20 @@
 * limitations under the License.
 */

#include <string.h>
#include <stdbool.h>
#include "expr.h"

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>

#include <string>
#include <unordered_map>

#include <android-base/stringprintf.h>
#include <android-base/strings.h>

#include "expr.h"

// Functions should:
//
//    - return a malloc()'d string
@@ -319,61 +319,22 @@ Value* Literal(const char* name, State* state, int argc, Expr* argv[]) {
    return StringValue(strdup(name));
}

Expr* Build(Function fn, YYLTYPE loc, int count, ...) {
    va_list v;
    va_start(v, count);
    Expr* e = reinterpret_cast<Expr*>(malloc(sizeof(Expr)));
    e->fn = fn;
    e->name = "(operator)";
    e->argc = count;
    e->argv = reinterpret_cast<Expr**>(malloc(count * sizeof(Expr*)));
    int i;
    for (i = 0; i < count; ++i) {
        e->argv[i] = va_arg(v, Expr*);
    }
    va_end(v);
    e->start = loc.start;
    e->end = loc.end;
    return e;
}

// -----------------------------------------------------------------
//   the function table
// -----------------------------------------------------------------

static int fn_entries = 0;
static int fn_size = 0;
NamedFunction* fn_table = NULL;

void RegisterFunction(const char* name, Function fn) {
    if (fn_entries >= fn_size) {
        fn_size = fn_size*2 + 1;
        fn_table = reinterpret_cast<NamedFunction*>(realloc(fn_table, fn_size * sizeof(NamedFunction)));
    }
    fn_table[fn_entries].name = name;
    fn_table[fn_entries].fn = fn;
    ++fn_entries;
}

static int fn_entry_compare(const void* a, const void* b) {
    const char* na = ((const NamedFunction*)a)->name;
    const char* nb = ((const NamedFunction*)b)->name;
    return strcmp(na, nb);
}
static std::unordered_map<std::string, Function> fn_table;

void FinishRegistration() {
    qsort(fn_table, fn_entries, sizeof(NamedFunction), fn_entry_compare);
void RegisterFunction(const std::string& name, Function fn) {
    fn_table[name] = fn;
}

Function FindFunction(const char* name) {
    NamedFunction key;
    key.name = name;
    NamedFunction* nf = reinterpret_cast<NamedFunction*>(bsearch(&key, fn_table, fn_entries,
            sizeof(NamedFunction), fn_entry_compare));
    if (nf == NULL) {
        return NULL;
Function FindFunction(const std::string& name) {
    if (fn_table.find(name) == fn_table.end()) {
        return nullptr;
    } else {
        return fn_table[name];
    }
    return nf->fn;
}

void RegisterBuiltins() {
+7 −33
Original line number Diff line number Diff line
@@ -21,11 +21,6 @@
#include <string>

#include "error_code.h"
#include "yydefs.h"

#define MAX_STRING_LEN 1024

typedef struct Expr Expr;

struct State {
    State(const std::string& script, void* cookie);
@@ -56,14 +51,15 @@ struct State {
#define VAL_STRING  1  // data will be NULL-terminated; size doesn't count null
#define VAL_BLOB    2

typedef struct {
struct Value {
    int type;
    ssize_t size;
    char* data;
} Value;
};

struct Expr;

typedef Value* (*Function)(const char* name, State* state,
                           int argc, Expr* argv[]);
using Function = Value* (*)(const char* name, State* state, int argc, Expr* argv[]);

struct Expr {
    Function fn;
@@ -100,43 +96,21 @@ Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]);
Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]);
Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]);

// Convenience function for building expressions with a fixed number
// of arguments.
Expr* Build(Function fn, YYLTYPE loc, int count, ...);

// Global builtins, registered by RegisterBuiltins().
Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]);
Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]);
Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]);


// For setting and getting the global error string (when returning
// NULL from a function).
void SetError(const char* message);  // makes a copy
const char* GetError();              // retains ownership
void ClearError();


typedef struct {
  const char* name;
  Function fn;
} NamedFunction;

// Register a new function.  The same Function may be registered under
// multiple names, but a given name should only be used once.
void RegisterFunction(const char* name, Function fn);
void RegisterFunction(const std::string& name, Function fn);

// Register all the builtins.
void RegisterBuiltins();

// Call this after all calls to RegisterFunction() but before parsing
// any scripts to finish building the function table.
void FinishRegistration();

// Find the Function for a given name; return NULL if no such function
// exists.
Function FindFunction(const char* name);

Function FindFunction(const std::string& name);

// --- convenience functions for use in functions ---

+24 −5
Original line number Diff line number Diff line
@@ -33,6 +33,25 @@ struct yy_buffer_state;
void yy_switch_to_buffer(struct yy_buffer_state* new_buffer);
struct yy_buffer_state* yy_scan_string(const char* yystr);

// Convenience function for building expressions with a fixed number
// of arguments.
static Expr* Build(Function fn, YYLTYPE loc, size_t count, ...) {
    va_list v;
    va_start(v, count);
    Expr* e = static_cast<Expr*>(malloc(sizeof(Expr)));
    e->fn = fn;
    e->name = "(operator)";
    e->argc = count;
    e->argv = static_cast<Expr**>(malloc(count * sizeof(Expr*)));
    for (size_t i = 0; i < count; ++i) {
        e->argv[i] = va_arg(v, Expr*);
    }
    va_end(v);
    e->start = loc.start;
    e->end = loc.end;
    return e;
}

%}

%locations
@@ -70,7 +89,7 @@ input: expr { *root = $1; }
;

expr:  STRING {
    $$ = reinterpret_cast<Expr*>(malloc(sizeof(Expr)));
    $$ = static_cast<Expr*>(malloc(sizeof(Expr)));
    $$->fn = Literal;
    $$->name = $1;
    $$->argc = 0;
@@ -91,9 +110,9 @@ expr: STRING {
|  IF expr THEN expr ENDIF           { $$ = Build(IfElseFn, @$, 2, $2, $4); }
|  IF expr THEN expr ELSE expr ENDIF { $$ = Build(IfElseFn, @$, 3, $2, $4, $6); }
| STRING '(' arglist ')' {
    $$ = reinterpret_cast<Expr*>(malloc(sizeof(Expr)));
    $$ = static_cast<Expr*>(malloc(sizeof(Expr)));
    $$->fn = FindFunction($1);
    if ($$->fn == NULL) {
    if ($$->fn == nullptr) {
        char buffer[256];
        snprintf(buffer, sizeof(buffer), "unknown function \"%s\"", $1);
        yyerror(root, error_count, buffer);
@@ -113,12 +132,12 @@ arglist: /* empty */ {
}
| expr {
    $$.argc = 1;
    $$.argv = reinterpret_cast<Expr**>(malloc(sizeof(Expr*)));
    $$.argv = static_cast<Expr**>(malloc(sizeof(Expr*)));
    $$.argv[0] = $1;
}
| arglist ',' expr {
    $$.argc = $1.argc + 1;
    $$.argv = reinterpret_cast<Expr**>(realloc($$.argv, $$.argc * sizeof(Expr*)));
    $$.argv = static_cast<Expr**>(realloc($$.argv, $$.argc * sizeof(Expr*)));
    $$.argv[$$.argc-1] = $3;
}
;
Loading