Skip to content

Commit

Permalink
Implement MIN and MAX functions
Browse files Browse the repository at this point in the history
Fixes gbdev#723
  • Loading branch information
Rangi42 committed Apr 7, 2021
1 parent de7d1fa commit eeb8320
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/asm/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ static struct KeywordMapping {
{"BANK", T_OP_BANK},
{"ALIGN", T_OP_ALIGN},

{"MIN", T_OP_MIN},
{"MAX", T_OP_MAX},

{"ROUND", T_OP_ROUND},
{"CEIL", T_OP_CEIL},
{"FLOOR", T_OP_FLOOR},
Expand Down Expand Up @@ -591,7 +594,7 @@ struct KeywordDictNode {
uint16_t children[0x60 - ' '];
struct KeywordMapping const *keyword;
/* Since the keyword structure is invariant, the min number of nodes is known at compile time */
} keywordDict[351] = {0}; /* Make sure to keep this correct when adding keywords! */
} keywordDict[354] = {0}; /* Make sure to keep this correct when adding keywords! */

/* Convert a char into its index into the dict */
static inline uint8_t dictIndex(char c)
Expand Down
17 changes: 17 additions & 0 deletions src/asm/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@ enum {
%type <nConstValue> uconst
%type <nConstValue> rs_uconst
%type <nConstValue> const_3bit
%type <nConstValue> min_args
%type <nConstValue> max_args
%type <sVal> reloc_8bit
%type <sVal> reloc_8bit_no_str
%type <sVal> reloc_16bit
Expand Down Expand Up @@ -482,6 +484,7 @@ enum {
%token T_OP_DEF "DEF"
%token T_OP_BANK "BANK"
%token T_OP_ALIGN "ALIGN"
%token T_OP_MIN "MIN" T_OP_MAX "MAX"
%token T_OP_SIN "SIN" T_OP_COS "COS" T_OP_TAN "TAN"
%token T_OP_ASIN "ASIN" T_OP_ACOS "ACOS" T_OP_ATAN "ATAN" T_OP_ATAN2 "ATAN2"
%token T_OP_FDIV "FDIV"
Expand Down Expand Up @@ -1393,6 +1396,8 @@ relocexpr_no_str : scoped_anon_id { rpn_Symbol(&$$, $1); }

lexer_ToggleStringExpansion(true);
}
| T_OP_MIN T_LPAREN min_args T_RPAREN { rpn_Number(&$$, $3); }
| T_OP_MAX T_LPAREN max_args T_RPAREN { rpn_Number(&$$, $3); }
| T_OP_ROUND T_LPAREN const T_RPAREN {
rpn_Number(&$$, fix_Round($3));
}
Expand Down Expand Up @@ -1484,6 +1489,18 @@ const_no_str : relocexpr_no_str {
}
;

min_args : const
| min_args T_COMMA const {
$$ = $1 < $3 ? $1 : $3;
}
;

max_args : const
| max_args T_COMMA const {
$$ = $1 > $3 ? $1 : $3;
}
;

string : T_STRING
| T_OP_STRSUB T_LPAREN string T_COMMA uconst T_COMMA uconst T_RPAREN {
strsubUTF8($$, sizeof($$), $3, $5, $7);
Expand Down
2 changes: 2 additions & 0 deletions src/asm/rgbasm.5
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@ String equates are not expanded within the parentheses.
.It Fn ISCONST arg Ta Returns 1 if Ar arg Ap s value is known by RGBASM (e.g. if it can be an argument to
.Ic IF ) ,
or 0 if only RGBLINK can compute its value.
.It Fn MIN args... Ta Returns the minimum operand, given at least one numeric operand.
.It Fn MAX args... Ta Returns the maximum operand, given at least one numeric operand.
.El
.Sh SECTIONS
Before you can start writing code, you must define a section.
Expand Down
8 changes: 8 additions & 0 deletions test/asm/math.asm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ ENDM
test (v 1) << (v 30) == (v $4000_0000)
test (v 2)**(v 30) == (v $4000_0000)

assert MIN(42) == 42
assert MIN(-10, 10) == -10
assert MIN(2, 1, 4, 3) == 1

assert MAX(42) == 42
assert MAX(-10, 10) == 10
assert MAX(2, 1, 4, 3) == 4

assert DIV(5.0, 2.0) == 2.5
assert DIV(-5.0, 2.0) == -2.5
assert DIV(-5.0, 0.0) == $8000_0000
Expand Down

0 comments on commit eeb8320

Please sign in to comment.