btcs

bitcoin script parser/evaluator/compiler/decompiler
git clone git://jb55.com/btcs
Log | Files | Refs | README | LICENSE

commit 28b0c89b7e0d2237a8b343275bbdc0eae7a575c2
parent 8c5edcb07f56102922ce11898d55e82080495ad0
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 12 Nov 2017 22:39:31 -0800

main working again

Diffstat:
Mlexer.l | 6++++++
Mmain.c | 27+++++++++++++++++++++------
Mop.c | 4++--
Mparser.y | 13+++++++++++--
Mscript.c | 2+-
Mval.c | 13++++++++++++-
6 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/lexer.l b/lexer.l @@ -23,6 +23,12 @@ [oO][pP]_ {} +-?[0-9] { + s64 i = strtoll(yytext, NULL, 10); + yylval.val = val_from_int(i); + return T_VAL; +} + [a-zA-Z0-9]+ { yylval.opcode = op_tokenize(yytext); return T_OP; diff --git a/main.c b/main.c @@ -10,6 +10,7 @@ extern FILE* yyin; char * g_reader_buf; char * g_reader_buf_top; +struct stack g_reader_stack; u32 g_reader_buf_cap; void yyerror(const char* s); @@ -19,25 +20,39 @@ int main() { size_t size; size_t bufsize = MAX_STACK_SIZE * MAX_STACK_SIZE; + int i; int compiled_len; u8 *buf = (u8*)malloc(bufsize); struct stack tmp_stack; alloc_arenas(0, MAX_STACK_SIZE, MAX_STACK_SIZE * MAX_STACK_SIZE); stack_init(&tmp_stack); + stack_init(&g_reader_stack); do { yyparse(); } while(!feof(yyin)); size = g_reader_buf_top - g_reader_buf; - script_serialize(g_reader_buf, buf, bufsize, &compiled_len); - script_eval(buf, size, &tmp_stack); - printf("script: "); - script_print_ops(g_reader_buf, g_reader_buf_top); - printf("stack: "); + printf("script "); + script_print_vals(&g_reader_stack); + script_serialize(&g_reader_stack, buf, bufsize, &compiled_len); + script_eval(buf, compiled_len, &tmp_stack); + + printf("script_hex "); + for(i = 0; i < compiled_len; ++i) + printf("%02x", buf[i]); + printf("\n"); + + printf("stack "); script_print_vals(&tmp_stack); + script_serialize(&tmp_stack, buf, bufsize, &compiled_len); + + printf("stack_hex "); + for(i = 0; i < compiled_len; ++i) + printf("%02x", buf[i]); + printf("\n"); - stack_free(&g_reader_buf); + stack_free(&g_reader_stack); stack_free(&tmp_stack); free_arenas(0); diff --git a/op.c b/op.c @@ -360,10 +360,10 @@ val_print(struct val val) { assert(val.ind != -1); n = num_pool_get(val.ind); assert(n); - printf("sn:%lu", n->val); + printf("%lu", n->val); break; case VT_OP: - printf("op:%d", val.ind); + printf("OP_%s", op_name(val.ind)); break; case VT_SMALLINT: printf("si:%d", val.ind); diff --git a/parser.y b/parser.y @@ -3,22 +3,29 @@ #include <stdio.h> #include "op.h" #include "stack.h" +#include "valstack.h" extern int yylex(); -extern struct stack reader_stack; +extern struct stack g_reader_stack; void yyerror(const char* s); %} %union { enum opcode opcode; + s64 integer; + struct val val; const char* str; } %token T_OP +%token T_INT +%token T_VAL %token T_NEWLINE T_QUIT T_EXAMPLE %type<opcode> T_OP +%type<integer> T_INT +%type<val> T_VAL %type<str> T_EXAMPLE %start script @@ -30,7 +37,9 @@ script: ; line: T_NEWLINE - | T_OP { stack_push_op(&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_EXAMPLE { ; } diff --git a/script.c b/script.c @@ -650,7 +650,7 @@ void script_print_vals(struct stack *stack) { while (p < stack->top) { struct val val; memcpy(&val, &*p++, sizeof(struct val)); - printf("s[%d] ", c++); + printf(" "); val_print(val); } putchar('\n'); diff --git a/val.c b/val.c @@ -36,6 +36,17 @@ val_serialize(struct val val, u16 *len, u8 *buf, int bufsize) { case VT_SCRIPTNUM: sn = num_pool_get(val.ind); assert(sn); + + /// TODO: if serialize_minimal + if (1) { + if (sn->val == -1) { *len = 1; *buf = OP_1NEGATE; return; } + if (sn->val == 0 ) { *len = 1; *buf = 0; return; } + if (sn->val >= 1 && sn->val <= 16 ) { + *len = 1; + *buf = OP_1 - 1 + sn->val; + return; + } + } sn_serialize(sn, buf+1, bufsize - 1, &valsize); assert(valsize <= 0xFF); *buf = (u8)valsize; @@ -54,7 +65,7 @@ val_serialize(struct val val, u16 *len, u8 *buf, int bufsize) { *len = *len + 1; } else { - assert(!"serialize bigger pushdatas"); + assert(!"serialize bigger pushdata"); } return; }