Added Hexadecimal encoding and binary encoding to numbers using '0x' and '0b'

This commit is contained in:
CPunch 2021-01-18 19:42:15 -06:00
parent 85503025dd
commit f8884c494c
3 changed files with 43 additions and 2 deletions

View File

@ -245,11 +245,38 @@ CToken parseString(CLexState *state) {
return makeToken(state, TOKEN_STRING); return makeToken(state, TOKEN_STRING);
} }
bool isHex(char c) {
return isNumerical(c) || ('A' <= c && 'F' >= c) || ('a' <= c && 'f' >= c);
}
CToken parseNumber(CLexState *state) { CToken parseNumber(CLexState *state) {
// consume number switch (peek(state)) {
while (isNumerical(peek(state))) case 'x': // hexadecimal number
next(state); next(state);
while (isHex(peek(state)))
next(state);
return makeToken(state, TOKEN_HEXNUMBER);
case 'b': // binary number
next(state);
while (peek(state) == '0' || peek(state) == '1')
next(state);
return makeToken(state, TOKEN_BINNUMBER);
default:
if (!isNumerical(peek(state)))
return makeError(state, "Unrecognized number encoding!");
// if it is a number, fall through and parse normally
}
// consume number
while (isNumerical(peek(state))) {
next(state);
}
if (peek(state) == '.' && isNumerical(peekNext(state))) { if (peek(state) == '.' && isNumerical(peekNext(state))) {
next(state); // consume '.' next(state); // consume '.'

View File

@ -40,6 +40,8 @@ typedef enum {
TOKEN_IDENTIFIER, TOKEN_IDENTIFIER,
TOKEN_STRING, // token.start is heap allocated and separate from the source string! TOKEN_STRING, // token.start is heap allocated and separate from the source string!
TOKEN_NUMBER, TOKEN_NUMBER,
TOKEN_HEXNUMBER,
TOKEN_BINNUMBER,
TOKEN_NIL, TOKEN_NIL,
TOKEN_TRUE, TOKEN_TRUE,
TOKEN_FALSE, TOKEN_FALSE,

View File

@ -407,6 +407,16 @@ static void number(CParseState *pstate, bool canAssign, Precedence prec) {
writeConstant(pstate, cosmoV_newNumber(num)); writeConstant(pstate, cosmoV_newNumber(num));
} }
static void hexnumber(CParseState *pstate, bool canAssign, Precedence prec) {
cosmo_Number num = strtol(pstate->previous.start + 2, NULL, 16); // +2 to skip the '0x'
writeConstant(pstate, cosmoV_newNumber(num));
}
static void binnumber(CParseState *pstate, bool canAssign, Precedence prec) {
cosmo_Number num = strtol(pstate->previous.start + 2, NULL, 2); // +2 to skip the '0b'
writeConstant(pstate, cosmoV_newNumber(num));
}
static void string(CParseState *pstate, bool canAssign, Precedence prec) { static void string(CParseState *pstate, bool canAssign, Precedence prec) {
CObjString *strObj = cosmoO_takeString(pstate->state, pstate->previous.start, pstate->previous.length); CObjString *strObj = cosmoO_takeString(pstate->state, pstate->previous.start, pstate->previous.length);
writeConstant(pstate, cosmoV_newObj((CObj*)strObj)); writeConstant(pstate, cosmoV_newObj((CObj*)strObj));
@ -922,6 +932,8 @@ ParseRule ruleTable[] = {
[TOKEN_IDENTIFIER] = {variable, NULL, PREC_NONE}, [TOKEN_IDENTIFIER] = {variable, NULL, PREC_NONE},
[TOKEN_STRING] = {string, NULL, PREC_NONE}, [TOKEN_STRING] = {string, NULL, PREC_NONE},
[TOKEN_NUMBER] = {number, NULL, PREC_NONE}, [TOKEN_NUMBER] = {number, NULL, PREC_NONE},
[TOKEN_HEXNUMBER] = {hexnumber, NULL, PREC_NONE},
[TOKEN_BINNUMBER] = {binnumber, NULL, PREC_NONE},
[TOKEN_NIL] = {literal, NULL, PREC_NONE}, [TOKEN_NIL] = {literal, NULL, PREC_NONE},
[TOKEN_TRUE] = {literal, NULL, PREC_NONE}, [TOKEN_TRUE] = {literal, NULL, PREC_NONE},
[TOKEN_FALSE] = {literal, NULL, PREC_NONE}, [TOKEN_FALSE] = {literal, NULL, PREC_NONE},