mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Implement INCHARMAP function (#1184)
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#ifndef RGBDS_ASM_CHARMAP_H
|
||||
#define RGBDS_ASM_CHARMAP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define DEFAULT_CHARMAP_NAME "main"
|
||||
@@ -19,6 +20,7 @@ void charmap_Set(char const *name);
|
||||
void charmap_Push(void);
|
||||
void charmap_Pop(void);
|
||||
void charmap_Add(char *mapping, uint8_t value);
|
||||
bool charmap_HasChar(char const *input);
|
||||
size_t charmap_Convert(char const *input, uint8_t *output);
|
||||
size_t charmap_ConvertNext(char const **input, uint8_t **output);
|
||||
|
||||
|
||||
@@ -425,6 +425,7 @@ pattern replaced by interpolating the format
|
||||
with its corresponding argument in
|
||||
.Ar args
|
||||
.Pq So %% Sc is replaced by the So % Sc character .
|
||||
.It Fn INCHARMAP str Ta Returns 1 if Ar str No has an entry in the current charmap, and 0 otherwise.
|
||||
.It Fn CHARLEN str Ta Returns the number of charmap entries in Ar str No with the current charmap.
|
||||
.It Fn CHARSUB str pos Ta Returns the substring for the charmap entry at Ar pos No in Ar str No (first character is position 1, last is position -1) with the current charmap.
|
||||
.El
|
||||
|
||||
@@ -187,6 +187,22 @@ void charmap_Add(char *mapping, uint8_t value)
|
||||
node->value = value;
|
||||
}
|
||||
|
||||
bool charmap_HasChar(char const *input)
|
||||
{
|
||||
struct Charmap const *charmap = *currentCharmap;
|
||||
struct Charnode const *node = &charmap->nodes[0];
|
||||
|
||||
for (; *input; input++) {
|
||||
size_t next = node->next[*input - 1];
|
||||
|
||||
if (!next)
|
||||
return false;
|
||||
node = &charmap->nodes[next];
|
||||
}
|
||||
|
||||
return node->isTerminal;
|
||||
}
|
||||
|
||||
size_t charmap_Convert(char const *input, uint8_t *output)
|
||||
{
|
||||
uint8_t *start = output;
|
||||
|
||||
@@ -206,6 +206,7 @@ static struct KeywordMapping {
|
||||
|
||||
{"CHARLEN", T_OP_CHARLEN},
|
||||
{"CHARSUB", T_OP_CHARSUB},
|
||||
{"INCHARMAP", T_OP_INCHARMAP},
|
||||
|
||||
{"INCLUDE", T_POP_INCLUDE},
|
||||
{"PRINT", T_POP_PRINT},
|
||||
@@ -571,7 +572,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[365] = {0}; // Make sure to keep this correct when adding keywords!
|
||||
} keywordDict[370] = {0}; // Make sure to keep this correct when adding keywords!
|
||||
|
||||
// Convert a char into its index into the dict
|
||||
static uint8_t dictIndex(char c)
|
||||
|
||||
@@ -606,6 +606,7 @@ enum {
|
||||
|
||||
%token T_OP_CHARLEN "CHARLEN"
|
||||
%token T_OP_CHARSUB "CHARSUB"
|
||||
%token T_OP_INCHARMAP "INCHARMAP"
|
||||
|
||||
%token <symName> T_LABEL "label"
|
||||
%token <symName> T_ID "identifier"
|
||||
@@ -1608,6 +1609,9 @@ relocexpr_no_str : scoped_anon_id { rpn_Symbol(&$$, $1); }
|
||||
| T_OP_CHARLEN T_LPAREN string T_RPAREN {
|
||||
rpn_Number(&$$, charlenUTF8($3));
|
||||
}
|
||||
| T_OP_INCHARMAP T_LPAREN string T_RPAREN {
|
||||
rpn_Number(&$$, charmap_HasChar($3));
|
||||
}
|
||||
| T_LPAREN relocexpr T_RPAREN { $$ = $2; }
|
||||
;
|
||||
|
||||
|
||||
28
test/asm/incharmap.asm
Normal file
28
test/asm/incharmap.asm
Normal file
@@ -0,0 +1,28 @@
|
||||
; default charmap 'main'
|
||||
charmap "a", 1
|
||||
charmap "ab", 2
|
||||
charmap "abc", 3
|
||||
|
||||
newcharmap second
|
||||
charmap "d", 4
|
||||
charmap "e", 5
|
||||
charmap {__ISO_8601_UTC__}, 6 ; expands with quotes
|
||||
|
||||
setcharmap main
|
||||
|
||||
assert incharmap("a")
|
||||
assert incharmap("ab")
|
||||
assert incharmap(strcat("ab", "c"))
|
||||
|
||||
assert !incharmap("") ; empty
|
||||
assert !incharmap("A") ; case sensitive
|
||||
assert !incharmap("aa") ; multiple chars "a" "a"
|
||||
assert !incharmap("d") ; unmapped char "d"
|
||||
assert !incharmap("bc") ; unmapped chars "b" "c"
|
||||
|
||||
setcharmap second
|
||||
|
||||
assert incharmap("d") ; now "d" is mapped
|
||||
assert !incharmap("a") ; only in 'main'
|
||||
assert !incharmap("bc") ; still unmapped chars
|
||||
assert incharmap({__ISO_8601_UTC__})
|
||||
0
test/asm/incharmap.err
Normal file
0
test/asm/incharmap.err
Normal file
0
test/asm/incharmap.out
Normal file
0
test/asm/incharmap.out
Normal file
Reference in New Issue
Block a user