commit - bc298316465678d2483ba33625c5b4c6a70c8066
commit + acf1403a4bf484e8fdddfbba698733bfcac8266d
blob - 3207aba3d37bbaa7e4064702c8554c2e3bf328c2
blob + db86711edf514c92a2c1cb54a87131189de1307b
--- np.y
+++ np.y
%token <v.str> STRING SYMBOL
%token <v.num> NUMBER
-%type <v.op> cast cexpr check expr funcall
+%type <v.op> cast cexpr check expr faccess funcall
%type <v.op> literal var varref
%type <v.proc> procname
* `expr '=' '=' expr` is ambiguous. furthermore, we're not
* interested in checking all the possibilities here.
*/
-cexpr : literal | varref | funcall ;
+cexpr : literal | varref | funcall | faccess ;
check : cexpr '=' '=' cexpr { $$ = op_cmp_eq($1, $4); } ;
-expr : literal | funcall | varref | check | cast ;
+expr : literal | funcall | varref | check | cast | faccess ;
cast : expr ':' U8 { $$ = op_cast($1, V_U8); }
| expr ':' U16 { $$ = op_cast($1, V_U16); }
| expr ':' U32 { $$ = op_cast($1, V_U32); }
| expr ':' STR { $$ = op_cast($1, V_STR); }
+ ;
+
+faccess : varref '.' SYMBOL { $$ = op_faccess($1, $3); }
+ | faccess '.' SYMBOL { $$ = op_faccess($1, $3); }
;
procname: SYMBOL {
blob - b63dac1d8755d3325c9ac524e93162f91b617940
blob + 42ce6187525e3d9564109b91e41b37c6585675d4
--- script.c
+++ script.c
op = newop(OP_CAST);
op->v.cast.expr = expr;
op->v.cast.totype = totype;
+
+ return op;
+}
+
+struct op *
+op_faccess(struct op *expr, char *field)
+{
+ struct op *op;
+
+ op = newop(OP_FACCESS);
+ op->v.faccess.expr = expr;
+ op->v.faccess.field = field;
return op;
}
}
#undef NUMCAST
+}
+
+int
+val_faccess(struct value *a, const char *field, struct value *ret)
+{
+ switch (a->type) {
+ case V_QID:
+ /* TODO: add path. needs uint64_t values thought! */
+ if (!strcmp(field, "vers")) {
+ ret->type = V_U32;
+ memcpy(&ret->v.u32, a->v.qid+1, 4);
+ } else if (!strcmp(field, "type")) {
+ ret->type = V_U8;
+ ret->v.u8 = *a->v.qid;
+ } else
+ return EVAL_ERR;
+ break;
+ default:
+ return EVAL_ERR;
+ }
+
+ return EVAL_OK;
}
void
printf(" == ");
pp_op(op->v.cmp_eq.b);
break;
+ case OP_FACCESS:
+ pp_op(op->v.faccess.expr);
+ printf(".%s", op->v.faccess.field);
+ break;
default:
printf(" ???[%d] ", op->type);
}
break;
+ case OP_FACCESS:
+ if ((ret = eval(op->v.faccess.expr)) != EVAL_OK)
+ return ret;
+ popv(&a);
+ if ((ret = val_faccess(&a, op->v.faccess.field, &b))
+ != EVAL_OK)
+ return ret;
+ pushv(&b);
+ break;
+
default:
fprintf(stderr, "invalid op, aborting.\n");
abort();
blob - 8c76ca4a7701c4b9bda43bdb8bce8c5dea410446
blob + 17f3b1a715d44b40d02f3bd814df9e1dd81ab96d
--- script.h
+++ script.h
OP_VAR,
OP_CAST,
OP_CMP_EQ,
+ OP_FACCESS,
};
struct proc;
struct op *a;
struct op *b;
} cmp_eq;
+ struct {
+ struct op *expr;
+ char *field;
+ } faccess;
} v;
};
struct op *op_lit_num(uint64_t);
struct op *op_cmp_eq(struct op *, struct op *);
struct op *op_cast(struct op *, int);
+struct op *op_faccess(struct op *, char *);
void ppf_val(FILE *, struct value *);
void pp_val(struct value *);
int val_trueish(struct value *);
int val_eq(struct value *, struct value *);
int val_cast(struct value *, int);
+int val_faccess(struct value *, const char *, struct value *);
void pp_op(struct op *);
void pp_block(struct op *);
int eval(struct op *);