commit 9fe02d49770a983fc3ecacc376e6b56528793c50
parent e2f92ff60ce794f7d50f3b838dd703aa4d0e157f
Author: William Casarin <jb55@jb55.com>
Date: Tue, 19 Dec 2017 11:22:13 -0800
ops: support scalar multiplication/division
Diffstat:
4 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/lexer.l b/lexer.l
@@ -2,7 +2,6 @@
%{
#include <stdio.h>
-#include <gmp.h>
#include "num.h"
#define YY_DECL int yylex()
diff --git a/num.c b/num.c
@@ -31,6 +31,8 @@ num_to_msat(struct num *num) {
return (int64_t)(val * MBTC);
case UNIT_BTC:
return (int64_t)(val * BTC);
+ case UNIT_NONE:
+ assert(!"got UNIT_NONE in num_to_msat");
}
}
@@ -48,6 +50,8 @@ num_to_msat(struct num *num) {
return val * MBTC;
case UNIT_BTC:
return val * BTC;
+ case UNIT_NONE:
+ assert(!"got UNIT_NONE in num_to_msat");
}
}
@@ -77,21 +81,44 @@ unit_msat_multiple(enum unit format) {
case UNIT_BITS: return BITS;
case UNIT_MBTC: return MBTC;
case UNIT_BTC: return BTC;
+ case UNIT_NONE: assert(!"got UNIT_NONE in num_to_msat");
}
}
void
num_mul(struct num *dst, struct num *a, struct num *b) {
+ assert(b->unit == UNIT_NONE);
dst->type = TYPE_INT;
dst->unit = UNIT_MSATOSHI;
- dst->intval = num_to_msat(a) * num_to_msat(b);
+ dst->intval = num_to_msat(a) * (b->type == TYPE_FLOAT? b->floatval
+ : b->intval);
}
void
num_div(struct num *dst, struct num *a, struct num *b) {
+ assert(b->unit == UNIT_NONE);
dst->type = TYPE_INT;
dst->unit = UNIT_MSATOSHI;
- dst->intval = num_to_msat(a) / num_to_msat(b);
+ dst->intval = num_to_msat(a) / (b->type == TYPE_FLOAT? b->floatval
+ : b->intval);
+}
+
+void
+num_init_float(struct num *num, double d, enum unit unit) {
+ num_init(num);
+ num->floatval = d;
+ num->type = TYPE_FLOAT;
+ num->unit = unit;
+ if (unit != UNIT_NONE) num_assign(num, num);
+}
+
+void
+num_init_int(struct num *num, int64_t val, enum unit unit) {
+ num_init(num);
+ num->intval = val;
+ num->type = TYPE_INT;
+ num->unit = unit;
+ if (unit != UNIT_NONE) num_assign(num, num);
}
void
@@ -157,5 +184,6 @@ unit_name(enum unit unit) {
case UNIT_BITS: return "bits";
case UNIT_MBTC: return "mBTC";
case UNIT_BTC: return "BTC";
+ case UNIT_NONE: assert(!"got UNIT_NONE in num_to_msat");
}
}
diff --git a/num.h b/num.h
@@ -19,6 +19,7 @@ enum unit {
UNIT_FINNEY,
UNIT_SATOSHI,
UNIT_MSATOSHI,
+ UNIT_NONE,
};
enum num_type {
diff --git a/parser.y b/parser.y
@@ -26,7 +26,7 @@ int g_print_unit;
%left T_PLUS T_MINUS
%left T_MULTIPLY T_DIVIDE
-%type<num> expr
+%type<num> expr unit_number number mul_expr div_expr
%start calc
@@ -40,24 +40,30 @@ line: T_NEWLINE
| expr T_NEWLINE { num_print(&$1, g_output_format, g_print_unit); }
;
-expr: T_INT T_UNIT { num_init(&$$);
- $$.intval = $1;
- $$.type = TYPE_INT;
- $$.unit = $2;
- num_assign(&$$, &$$);
- }
- | T_FLOAT T_UNIT { num_init(&$$);
- $$.floatval = $1;
- $$.type = TYPE_FLOAT;
- $$.unit = $2;
- num_assign(&$$, &$$);
- }
+unit_number:
+ T_INT T_UNIT { num_init_int(&$$, $1, $2); }
+ | T_FLOAT T_UNIT { num_init_float(&$$, $1, $2); }
+ ;
+
+
+number: T_INT { num_init_int(&$$, $1, UNIT_NONE); }
+ | T_FLOAT { num_init_float(&$$, $1, UNIT_NONE); }
+ ;
+
+mul_expr: number T_MULTIPLY unit_number { num_mul(&$$, &$3, &$1); }
+ | unit_number T_MULTIPLY number { num_mul(&$$, &$1, &$3); }
+ ;
+
+div_expr: number T_DIVIDE unit_number { num_div(&$$, &$3, &$1); }
+ | unit_number T_DIVIDE number { num_div(&$$, &$1, &$3); }
+ ;
+
+expr: unit_number
| expr T_PLUS expr { num_add(&$$, &$1, &$3); }
| expr T_MINUS expr { num_sub(&$$, &$1, &$3); }
- /* | expr T_MULTIPLY expr { num_mul(&$$, &$1, &$3); } */
- /* | expr T_DIVIDE expr { num_div(&$$, &$1, &$3); } */
+ | mul_expr
+ | div_expr
| T_LEFT expr T_RIGHT { num_init(&$$); num_assign(&$$, &$2); }
;
%%
-