libidav/davqlexec.c

changeset 123
806c4dccf2ae
parent 104
6fb4d24d9df9
child 124
41939c8f3f9c
--- a/libidav/davqlexec.c	Fri May 29 13:12:25 2015 +0200
+++ b/libidav/davqlexec.c	Fri May 29 14:16:45 2015 +0200
@@ -129,9 +129,209 @@
     
     // TODO: get property list
     
-    
+    UcxBuffer *bcode = dav_compile_lexpr(st->where);
+    printf("bcode: %.*s\n", bcode->size, bcode->space);
+}
+
+static int count_func_args(DavQLExpression *expr) {
+    int count = 0;
+    DavQLExpression *arg = expr->right;
+    while(arg) {
+        count++;
+        if(arg->op == DAVQL_ARGLIST) {
+            arg = arg->right;
+        } else {
+            break;
+        }
+    }
+    return count;
 }
 
-int dav_eval_lexpr(DavResource *res, DavQLExpression *lexpr) {
+static int add_cmd(UcxBuffer *bcode, DavQLExpression *expr) {
+    if(!expr) {
+        return 0;
+    }
     
+    int numcmd = 1;
+    sstr_t src = expr->srctext;
+    switch(expr->type) {
+        case DAVQL_NUMBER: {
+            ucx_bprintf(bcode, "number(%.*s) ", src.length, src.ptr);
+            break;
+        }
+        case DAVQL_STRING: {
+            // TODO: check format specifier
+            ucx_bprintf(bcode, "string(%.*s) ", src.length, src.ptr);
+            break;
+        }
+        case DAVQL_TIMESTAMP: {
+            ucx_bprintf(bcode, "timestamp(%.*s) ", src.length, src.ptr);
+            break;
+        }
+        case DAVQL_IDENTIFIER: {
+            // TODO: check identifier type
+            ucx_bprintf(bcode, "identifier(%.*s) ", src.length, src.ptr);
+            break;
+        }
+        case DAVQL_UNARY: {
+            numcmd += add_cmd(bcode, expr->left);
+            switch(expr->op) {
+                case DAVQL_ADD: {
+                    ucx_bprintf(bcode, "unop_add ");
+                    break;
+                }
+                case DAVQL_SUB: {
+                    ucx_bprintf(bcode, "unop_sub ");
+                    break;
+                }
+                case DAVQL_NEG: {
+                    ucx_bprintf(bcode, "unop_neg ");
+                    break;
+                }
+            }
+            break;
+        }
+        case DAVQL_BINARY: {
+            numcmd += add_cmd(bcode, expr->left);
+            numcmd += add_cmd(bcode, expr->right);
+            switch(expr->op) {
+                case DAVQL_ADD: {
+                    ucx_bprintf(bcode, "binop_add ");
+                    break;
+                }
+                case DAVQL_SUB: {
+                    ucx_bprintf(bcode, "binop_sub ");
+                    break;
+                }
+                case DAVQL_MUL: {
+                    ucx_bprintf(bcode, "binop_sub ");
+                    break;
+                }
+                case DAVQL_DIV: {
+                    ucx_bprintf(bcode, "binop_sub ");
+                    break;
+                }
+                case DAVQL_AND: {
+                    ucx_bprintf(bcode, "binop_sub ");
+                    break;
+                }
+                case DAVQL_OR: {
+                    ucx_bprintf(bcode, "binop_sub ");
+                    break;
+                }
+                case DAVQL_XOR: {
+                    ucx_bprintf(bcode, "binop_sub ");
+                    break;
+                }
+            }
+            break;
+        }
+        case DAVQL_LOGICAL: {
+            if(expr->left && expr->right && expr->op != DAVQL_LOR) {
+                numcmd += add_cmd(bcode, expr->left);
+                numcmd += add_cmd(bcode, expr->right);
+            }
+            
+            switch(expr->op) {
+                case DAVQL_NOOP: {
+                    break;
+                }
+                case DAVQL_NOT: {
+                    numcmd += add_cmd(bcode, expr->left);
+                    ucx_bprintf(bcode, "op_not ");
+                    break;
+                }
+                case DAVQL_LAND: {
+                    ucx_bprintf(bcode, "op_land ");
+                    break;
+                }
+                case DAVQL_LOR: {
+                    int nleft = add_cmd(bcode, expr->left);
+                    ucx_bprintf(bcode, "op_lor_left(    ) ");
+                    char *bcode_pos = bcode->space + bcode->size - 6;
+                    int nright = add_cmd(bcode, expr->right);
+                    char buf[5];
+                    ssize_t n = snprintf(buf, 4, "%d", nright);
+                    memcpy(bcode_pos, buf, n);
+                    ucx_bprintf(bcode, "op_lor ");
+                    numcmd += nleft + nright;
+                    break;
+                }
+                case DAVQL_LXOR: {
+                    ucx_bprintf(bcode, "op_lxor ");
+                    break;
+                }
+                case DAVQL_EQ: {
+                    ucx_bprintf(bcode, "op_eq ");
+                    break;
+                }
+                case DAVQL_NEQ: {
+                    ucx_bprintf(bcode, "op_neq ");
+                    break;
+                }
+                case DAVQL_LT: {
+                   ucx_bprintf(bcode, "op_lt ");
+                    break;
+                }
+                case DAVQL_GT: {
+                    ucx_bprintf(bcode, "op_gt ");
+                    break;
+                }
+                case DAVQL_LE: {
+                    ucx_bprintf(bcode, "op_le ");
+                    break;
+                }
+                case DAVQL_GE: {
+                    ucx_bprintf(bcode, "op_ge ");
+                    break;
+                }
+                case DAVQL_LIKE: {
+                    ucx_bprintf(bcode, "op_like ");
+                    break;
+                }
+                case DAVQL_UNLIKE: {
+                    ucx_bprintf(bcode, "op_unlike ");
+                    break;
+                }
+            }
+            break;
+        }
+        case DAVQL_FUNCCALL: {
+            switch(expr->op) {
+                case DAVQL_CALL: {
+                    int nright = add_cmd(bcode, expr->right);
+                    // TODO: count args
+                    DavQLExpression *funcid = expr->left;
+                    if(!funcid && funcid->type != DAVQL_IDENTIFIER) {
+                        // fail
+                        return -1;
+                    }
+                    
+                    ucx_bprintf(bcode, "funcname(%.*s) numargs(%d) call ", funcid->srctext.length, funcid->srctext.ptr, count_func_args(expr));
+                    numcmd = 3;
+                    numcmd += nright;
+                    break;
+                }
+                case DAVQL_ARGLIST: {
+                    numcmd = 0;
+                    numcmd += add_cmd(bcode, expr->left);
+                    numcmd += add_cmd(bcode, expr->right);
+                    break;
+                }
+            }
+            break;
+        }
+    }
+    return numcmd;
 }
+
+UcxBuffer* dav_compile_lexpr(DavQLExpression *lexpr) {
+    UcxBuffer *bcode = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND);
+    if(!bcode) {
+        return NULL;
+    }
+    
+    int numcmd = add_cmd(bcode, lexpr);
+    
+    return bcode;
+}

mercurial