diff --git a/builtin/builtin.c b/builtin/builtin.c new file mode 100644 index 0000000..f29c97d --- /dev/null +++ b/builtin/builtin.c @@ -0,0 +1,37 @@ +#include "../include/share.h" +#include "../compiler/summoner.h" + +typedef struct +{ + const char *name; + BasicType *parameters; + int parameter_count; + BasicType return_type; + const char *op_codes; +} BuiltinFun; + +static BasicType sha3_params[] = {HEX_TYPE}; +static BasicType sha256_params[] = {HEX_TYPE}; +static BasicType abs_params[] = {INT_TYPE}; +static BasicType min_params[] = {INT_TYPE, INT_TYPE}; +static BasicType max_params[] = {INT_TYPE, INT_TYPE}; +static BasicType check_tx_sig_params[] = {PUBKEY_TYPE, SIG_TYPE}; +static BasicType check_msg_sig_params[] = {PUBKEY_TYPE, HASH_TYPE, SIG_TYPE}; +static BasicType below_params[] = {INT_TYPE, BOOLEAN_TYPE}; +static BasicType above_params[] = {INT_TYPE, BOOLEAN_TYPE}; +static BasicType lock_params[] = {AMOUNT_TYPE, ASSET_TYPE, HEX_TYPE, HEX_TYPE}; +static BasicType verify_params[] = {BOOLEAN_TYPE}; + +BuiltinFun builtin_funs[] = { + {"sha3", sha3_params, ARRAY_SIZE(sha3_params), HASH_TYPE, "SHA3"}, + {"sha256", sha256_params, ARRAY_SIZE(sha256_params), HASH_TYPE, "SHA256"}, + {"abs", abs_params, ARRAY_SIZE(abs_params), INT_TYPE, "ABS"}, + {"min", min_params, ARRAY_SIZE(min_params), INT_TYPE, "MIN"}, + {"max", max_params, ARRAY_SIZE(max_params), INT_TYPE, "MAX"}, + {"check_tx_sig", check_tx_sig_params, ARRAY_SIZE(check_tx_sig_params), BOOLEAN_TYPE, "TXSIGHASH SWAP CHECKSIG"}, + {"check_msg_sig", check_msg_sig_params, ARRAY_SIZE(check_msg_sig_params), BOOLEAN_TYPE, "CHECKSIG"}, + {"below", below_params, ARRAY_SIZE(below_params), BOOLEAN_TYPE, "BLOCKHEIGHT GREATERTHAN"}, + {"above", above_params, ARRAY_SIZE(above_params), BOOLEAN_TYPE, "BLOCKHEIGHT LESSTHAN"}, + {"lock", lock_params, ARRAY_SIZE(lock_params), VOID_TYPE, ""}, + {"verify", verify_params, ARRAY_SIZE(verify_params), VOID_TYPE, "VERIFY"}, +}; diff --git a/compiler/create.c b/compiler/create.c index 44b503d..18197b3 100644 --- a/compiler/create.c +++ b/compiler/create.c @@ -103,6 +103,11 @@ Statement *alloc_assign_stmt(char *variable, Expression *operand) return stmt; } +Statement *alloc_compound_assign_stmt(char *variable, ExpressionKind kind, Expression *operand) +{ + return alloc_assign_stmt(variable, alloc_binary_expression(kind, alloc_identifier_expression(variable), operand)); +} + Statement *alloc_if_stmt(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block) { Statement *stmt = alloc_stmt(IF_STATEMENT); diff --git a/compiler/grammar.y b/compiler/grammar.y index 785e399..d95f683 100644 --- a/compiler/grammar.y +++ b/compiler/grammar.y @@ -30,11 +30,11 @@ int yyerror(const char *s); %token STRING_LITERAL %token IDENTIFIER %token VAR CONST FUNCTION IF ELSE FOR RETURN BREAK CONTINUE NIL -%token BOOL_T INT_T DOUBLE_T STRING_T +%token BOOL_T INT_T DOUBLE_T STRING_T ASSET_T HASH_T AMOUNT_T PUBKEY_T SIG_T HEX_T %type expr bool_expr func_call_expr literal %type variable_declaration variable_declaration_list -%type stmt if_stmt return_stmt declaration_stmt variable_declaration_stmt const_stmt +%type stmt if_stmt return_stmt declaration_stmt assign_stmt compound_assign_stmt variable_declaration_stmt const_stmt %type stmt_list %type block %type elseif elseif_list @@ -44,7 +44,7 @@ int yyerror(const char *s); %type definition_list %type argument_list -%nonassoc '=' DECL_ASSIGN +%nonassoc '=' ADD_ASSIGN SUB_ASSIGN MUL_ASSIGN DIV_ASSIGN DECL_ASSIGN %left AND OR %nonassoc EQ NE %nonassoc '>' '<' LE GE @@ -100,14 +100,26 @@ stmt_list: ; stmt: - IDENTIFIER '=' expr { $$ = alloc_assign_stmt($1, $3); } - | expr { $$ = alloc_expression_stmt($1); } + expr { $$ = alloc_expression_stmt($1); } | block { $$ = alloc_block_stmt($1); } + | assign_stmt | if_stmt | declaration_stmt | return_stmt ; +assign_stmt: + IDENTIFIER '=' expr { $$ = alloc_assign_stmt($1, $3); } + | compound_assign_stmt + ; + +compound_assign_stmt: + IDENTIFIER ADD_ASSIGN expr { $$ = alloc_compound_assign_stmt($1, ADD_EXPRESSION, $3); } + | IDENTIFIER SUB_ASSIGN expr { $$ = alloc_compound_assign_stmt($1, SUB_EXPRESSION, $3); } + | IDENTIFIER MUL_ASSIGN expr { $$ = alloc_compound_assign_stmt($1, MUL_EXPRESSION, $3); } + | IDENTIFIER DIV_ASSIGN expr { $$ = alloc_compound_assign_stmt($1, DIV_EXPRESSION, $3); } + ; + const_stmt: CONST IDENTIFIER '=' expr { $$ = alloc_const_declaration_stmt($2, NULL, $4); } | CONST IDENTIFIER type_specifier '=' expr { $$ = alloc_const_declaration_stmt($2, $3, $5); } @@ -139,6 +151,12 @@ type_specifier: | INT_T { $$ = alloc_type_specifier(INT_TYPE, NULL); } | DOUBLE_T { $$ = alloc_type_specifier(DOUBLE_TYPE, NULL); } | STRING_T { $$ = alloc_type_specifier(STRING_TYPE, NULL); } + | ASSET_T { $$ = alloc_type_specifier(ASSET_TYPE, NULL); } + | HASH_T { $$ = alloc_type_specifier(HASH_TYPE, NULL); } + | AMOUNT_T { $$ = alloc_type_specifier(AMOUNT_TYPE, NULL); } + | PUBKEY_T { $$ = alloc_type_specifier(PUBKEY_TYPE, NULL); } + | SIG_T { $$ = alloc_type_specifier(SIG_TYPE, NULL); } + | HEX_T { $$ = alloc_type_specifier(HEX_TYPE, NULL); } ; return_stmt: diff --git a/compiler/lex.l b/compiler/lex.l index b9999b8..5c32104 100644 --- a/compiler/lex.l +++ b/compiler/lex.l @@ -58,6 +58,10 @@ void lex_err(char *str) { } ":=" return DECL_ASSIGN; +"+=" return ADD_ASSIGN; +"-=" return SUB_ASSIGN; +"*=" return MUL_ASSIGN; +"/=" return DIV_ASSIGN; ">=" return GE; "<=" return LE; "==" return EQ; @@ -78,6 +82,12 @@ void lex_err(char *str) { "int" return INT_T; "double" return DOUBLE_T; "string" return STRING_T; +"asset" return ASSET_T; +"hash" return HASH_T; +"amount" return AMOUNT_T; +"pubkey" return PUBKEY_T; +"sig" return SIG_T; +"hex" return HEX_T; "true"|"false" { yylval.int_value = strcmp(yytext, "false"); diff --git a/compiler/summoner.h b/compiler/summoner.h index 2160d00..9d40a94 100644 --- a/compiler/summoner.h +++ b/compiler/summoner.h @@ -36,6 +36,13 @@ typedef enum INT_TYPE, DOUBLE_TYPE, STRING_TYPE, + ASSET_TYPE, + HASH_TYPE, + AMOUNT_TYPE, + PUBKEY_TYPE, + SIG_TYPE, + HEX_TYPE, + VOID_TYPE, STRUCT_TYPE, } BasicType; @@ -159,6 +166,7 @@ typedef struct IfStatement Statement *alloc_stmt(StatementKind kind); Statement *alloc_assign_stmt(char *variable, Expression *operand); +Statement *alloc_compound_assign_stmt(char *variable, ExpressionKind kind, Expression *operand); Statement *alloc_block_stmt(Block *block); Statement *alloc_if_stmt(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block); Declaration *alloc_declaration(char *name, TypeSpecifier *type, Expression *initializer); diff --git a/include/share.h b/include/share.h new file mode 100644 index 0000000..1e95950 --- /dev/null +++ b/include/share.h @@ -0,0 +1,6 @@ +#ifndef PRIVATE_SHARE_H_INCLUDED +#define PRIVATE_SHARE_H_INCLUDED + +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +#endif