commit 5f236ed0bfcaaad0f1af33a0d99985b57395d1a5
parent 60d748d3e15ba89806c77207e69e039ae03facc3
Author: William Casarin <jb55@jb55.com>
Date: Wed, 27 Dec 2017 21:25:42 -0800
script: implement raw, inline script data
One down side is that you don't see the decompiled ops like you get with
bitcoin-tx. Perhaps I should run VT_RAW through a decompilation phase after
that's implemented.
Closes #20
Diffstat:
7 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/lexer.l b/lexer.l
@@ -31,12 +31,23 @@
return T_STR;
}
+0x[a-fA-F0-9]+ {
+ char * t = yytext + 2;
+ if (strlen(t) % 2 != 0) {
+ yylval.str = "Invalid raw string, it must have even length";
+ return T_ERR;
+ }
+ yylval.str = t;
+ return T_RAW;
+}
+
@[a-fA-F0-9]+ {
- if (strlen(yytext + 1) % 2 != 0) {
- yylval.str = "Invalid data string, byte string must have even length";
+ char *t = yytext + 1;
+ if (strlen(t) % 2 != 0) {
+ yylval.str = "Invalid data string, it must have even length";
return T_ERR;
}
- yylval.str = yytext + 1;
+ yylval.str = t;
return T_DATA;
}
diff --git a/op.c b/op.c
@@ -381,6 +381,13 @@ val_print(struct val val) {
print_bytes(data, len, 0);
break;
}
+ case VT_RAW: {
+ u32 len;
+ u8 *data = byte_pool_get(val.ind, &len);
+ printf("0x");
+ print_bytes(data, len, 0);
+ break;
+ }
default:
assert(!"val_print data");
}
diff --git a/parser.y b/parser.y
@@ -23,6 +23,7 @@ void yyerror(const char* s);
%token T_INT
%token T_VAL
%token T_DATA
+%token T_RAW
%token T_STR
%token T_COMMENT
%token T_ERR
@@ -31,6 +32,7 @@ void yyerror(const char* s);
%type<opcode> T_OP
%type<integer> T_INT
%type<str> T_DATA
+%type<str> T_RAW
%type<str> T_STR
%type<val> T_VAL
%type<str> T_EXAMPLE
@@ -46,10 +48,11 @@ script:
line: T_NEWLINE
| T_COMMENT
+ | T_RAW { script_push_raw(&g_reader_stack, $1); }
| T_INT { script_push_int(&g_reader_stack, $1); }
| T_VAL { stack_push_val(&g_reader_stack, $1); }
| T_OP { stack_push_op(&g_reader_stack, $1); }
- | T_DATA { script_push_datastr(&g_reader_stack, $1); }
+ | T_DATA { script_push_datastr(&g_reader_stack, $1, 0); }
| T_STR { script_push_str(&g_reader_stack, $1); }
| T_ERR { parse_error($1); }
| T_EXAMPLE { script_handle_input(&g_reader_stack, $1); }
diff --git a/script.c b/script.c
@@ -437,7 +437,6 @@ script_eval(const u8 *script, size_t script_size, struct stack *stack,
struct val val = stack_top_val(stack, (-(n->val))-1);
if (opcode == OP_ROLL)
stack_erase(stack, -(n->val) - 1);
- /* stack.erase(stack.end()-n-1); */
stack_push_val(stack, val);
}
break;
@@ -733,7 +732,6 @@ void script_print_vals(struct stack *stack) {
putchar('\n');
}
-
void
script_push_int(struct stack *script, s64 intval) {
/* u16 len; */
@@ -748,7 +746,7 @@ script_push_int(struct stack *script, s64 intval) {
void
-script_push_str(struct stack *script, char *str) {
+script_push_str(struct stack *script, const char *str) {
struct val val;
u16 ind;
u8 *bytes;
@@ -762,7 +760,7 @@ script_push_str(struct stack *script, char *str) {
}
void
-script_push_datastr(struct stack *script, const char *str) {
+script_push_datastr(struct stack *script, const char *str, int raw) {
int count = 0;
u8 *bytes;
const char *p = str;
@@ -778,7 +776,7 @@ script_push_datastr(struct stack *script, const char *str) {
p += 2;
}
- val.type = VT_DATA;
+ val.type = raw ? VT_RAW : VT_DATA;
val.ind = ind;
stack_push_val(script, val);
@@ -786,6 +784,12 @@ script_push_datastr(struct stack *script, const char *str) {
void
+script_push_raw(struct stack *stack, const char *data) {
+ script_push_datastr(stack, data, 1);
+}
+
+
+void
script_serialize(struct stack *stack, u8 *buf, int buflen, int* len) {
struct val *valp;
void **sp;
diff --git a/script.h b/script.h
@@ -17,8 +17,9 @@ void script_print_ops(char * buf, size_t size);
void script_print_vals(struct stack *);
void script_push_int(struct stack *, s64);
-void script_push_str(struct stack *script, char *str);
-void script_push_datastr(struct stack *, const char *str);
+void script_push_str(struct stack *script, const char *str);
+void script_push_raw(struct stack *, const char *str);
+void script_push_datastr(struct stack *, const char *str, int israw);
void
script_serialize(struct stack *stack, u8 *buf, int buflen, int* len);
diff --git a/val.c b/val.c
@@ -56,6 +56,12 @@ val_serialize(struct val val, u32 *len, u8 *buf, int bufsize) {
*len = 1;
*buf = val.ind & 0xFF;
return;
+ case VT_RAW: {
+ u8 *p;
+ p = byte_pool_get(val.ind, len);
+ memcpy(buf, p, *len);
+ return;
+ }
case VT_DATA: {
u8 *p;
p = byte_pool_get(val.ind, len);
diff --git a/val.h b/val.h
@@ -9,6 +9,7 @@ enum valtype {
VT_SCRIPTNUM=0,
VT_SMALLINT,
VT_OP,
+ VT_RAW,
VT_DATA,
VT_N
};