mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Implement INCHARMAP function (#1184)
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#ifndef RGBDS_ASM_CHARMAP_H
|
#ifndef RGBDS_ASM_CHARMAP_H
|
||||||
#define RGBDS_ASM_CHARMAP_H
|
#define RGBDS_ASM_CHARMAP_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define DEFAULT_CHARMAP_NAME "main"
|
#define DEFAULT_CHARMAP_NAME "main"
|
||||||
@@ -19,6 +20,7 @@ void charmap_Set(char const *name);
|
|||||||
void charmap_Push(void);
|
void charmap_Push(void);
|
||||||
void charmap_Pop(void);
|
void charmap_Pop(void);
|
||||||
void charmap_Add(char *mapping, uint8_t value);
|
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_Convert(char const *input, uint8_t *output);
|
||||||
size_t charmap_ConvertNext(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
|
with its corresponding argument in
|
||||||
.Ar args
|
.Ar args
|
||||||
.Pq So %% Sc is replaced by the So % Sc character .
|
.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 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.
|
.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
|
.El
|
||||||
|
|||||||
@@ -187,6 +187,22 @@ void charmap_Add(char *mapping, uint8_t value)
|
|||||||
node->value = 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)
|
size_t charmap_Convert(char const *input, uint8_t *output)
|
||||||
{
|
{
|
||||||
uint8_t *start = output;
|
uint8_t *start = output;
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ static struct KeywordMapping {
|
|||||||
|
|
||||||
{"CHARLEN", T_OP_CHARLEN},
|
{"CHARLEN", T_OP_CHARLEN},
|
||||||
{"CHARSUB", T_OP_CHARSUB},
|
{"CHARSUB", T_OP_CHARSUB},
|
||||||
|
{"INCHARMAP", T_OP_INCHARMAP},
|
||||||
|
|
||||||
{"INCLUDE", T_POP_INCLUDE},
|
{"INCLUDE", T_POP_INCLUDE},
|
||||||
{"PRINT", T_POP_PRINT},
|
{"PRINT", T_POP_PRINT},
|
||||||
@@ -571,7 +572,7 @@ struct KeywordDictNode {
|
|||||||
uint16_t children[0x60 - ' '];
|
uint16_t children[0x60 - ' '];
|
||||||
struct KeywordMapping const *keyword;
|
struct KeywordMapping const *keyword;
|
||||||
// Since the keyword structure is invariant, the min number of nodes is known at compile time
|
// 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
|
// Convert a char into its index into the dict
|
||||||
static uint8_t dictIndex(char c)
|
static uint8_t dictIndex(char c)
|
||||||
|
|||||||
@@ -606,6 +606,7 @@ enum {
|
|||||||
|
|
||||||
%token T_OP_CHARLEN "CHARLEN"
|
%token T_OP_CHARLEN "CHARLEN"
|
||||||
%token T_OP_CHARSUB "CHARSUB"
|
%token T_OP_CHARSUB "CHARSUB"
|
||||||
|
%token T_OP_INCHARMAP "INCHARMAP"
|
||||||
|
|
||||||
%token <symName> T_LABEL "label"
|
%token <symName> T_LABEL "label"
|
||||||
%token <symName> T_ID "identifier"
|
%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 {
|
| T_OP_CHARLEN T_LPAREN string T_RPAREN {
|
||||||
rpn_Number(&$$, charlenUTF8($3));
|
rpn_Number(&$$, charlenUTF8($3));
|
||||||
}
|
}
|
||||||
|
| T_OP_INCHARMAP T_LPAREN string T_RPAREN {
|
||||||
|
rpn_Number(&$$, charmap_HasChar($3));
|
||||||
|
}
|
||||||
| T_LPAREN relocexpr T_RPAREN { $$ = $2; }
|
| 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