From 15aa4d5b32a9e670cb5fdc9ea9772ded446404ea Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 28 Jun 2021 10:45:55 -0400 Subject: [PATCH] flesh out string -> integer functions --- docs/metadesk_reference.md | 36 +++++--- .../static_site_generator.c | 4 +- source/md.h | 7 +- source/md_c_helpers.c | 4 +- source/md_impl.c | 92 ++++++++++++------- 5 files changed, 94 insertions(+), 49 deletions(-) diff --git a/docs/metadesk_reference.md b/docs/metadesk_reference.md index 03622c3..f631770 100644 --- a/docs/metadesk_reference.md +++ b/docs/metadesk_reference.md @@ -808,19 +808,6 @@ main: return: MD_String8, }; -@send(Strings) -@func MD_I64FromString: { - string: MD_String8, - radix: MD_u32, - return: MD_i64, -}; - -@send(Strings) -@func MD_F64FromString: { - string: MD_String8, - return: MD_f64, -}; - @send(Strings) @func MD_CalculateCStringLength: { cstr: *char, @@ -835,6 +822,29 @@ main: return: MD_String8 }; +//////////////////////////////// +//~ Numeric Strings + +@send(Strings) +@func MD_U64FromString: { + string: MD_String8, + radix: MD_u32, + return: MD_u64, +}; + +@send(Strings) +@func MD_CStyleIntFromString: { + string: MD_String8, + return: MD_i64, +}; + +@send(Strings) +@func MD_F64FromString: { + string: MD_String8, + return: MD_f64, +}; + + //////////////////////////////// //~ Enum/Flag Strings diff --git a/samples/static_site_generator/static_site_generator.c b/samples/static_site_generator/static_site_generator.c index 6285f25..6ff48ba 100644 --- a/samples/static_site_generator/static_site_generator.c +++ b/samples/static_site_generator/static_site_generator.c @@ -352,14 +352,14 @@ MakeDateString(MD_Node *date) } } - if(year && month && day) + if(!MD_NodeIsNil(year) && !MD_NodeIsNil(month) && !MD_NodeIsNil(day)) { char *month_names[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", }; - int month_idx = MD_I64FromString(month->string, 10)-1; + MD_u64 month_idx = MD_U64FromString(month->string, 10) - 1; if(month_idx >= 0 && month_idx < sizeof(month_names)/sizeof(month_names[0])) { result = MD_PushStringF("%.*s %s %.*s", diff --git a/source/md.h b/source/md.h index fff5b51..1aa4a89 100644 --- a/source/md.h +++ b/source/md.h @@ -666,12 +666,15 @@ MD_FUNCTION void MD_PushStringToList(MD_String8List *list, MD_String8 MD_FUNCTION void MD_PushStringListToList(MD_String8List *list, MD_String8List *to_push); MD_FUNCTION MD_String8List MD_SplitString(MD_String8 string, int split_count, MD_String8 *splits); MD_FUNCTION MD_String8 MD_JoinStringList(MD_String8List list, MD_String8 separator); -MD_FUNCTION MD_i64 MD_I64FromString(MD_String8 string, MD_u32 radix); -MD_FUNCTION MD_f64 MD_F64FromString(MD_String8 string); MD_FUNCTION MD_u64 MD_CalculateCStringLength(char *cstr); MD_FUNCTION MD_String8 MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 separator); +//~ Numeric Strings +MD_FUNCTION MD_u64 MD_U64FromString(MD_String8 string, MD_u32 radix); +MD_FUNCTION MD_i64 MD_CStyleIntFromString(MD_String8 string); +MD_FUNCTION MD_f64 MD_F64FromString(MD_String8 string); + //~ Enum/Flag Strings MD_FUNCTION MD_String8 MD_StringFromNodeKind(MD_NodeKind kind); MD_FUNCTION MD_String8List MD_StringListFromNodeFlags(MD_NodeFlags flags); diff --git a/source/md_c_helpers.c b/source/md_c_helpers.c index 14e0ed2..826eec8 100644 --- a/source/md_c_helpers.c +++ b/source/md_c_helpers.c @@ -462,7 +462,9 @@ MD_C_EvaluateExpr_I64(MD_C_Expr *expr) _MD_BinaryOp(Multiply, *); _MD_BinaryOp(Divide, /); #undef _MD_BinaryOp - case MD_C_ExprKind_Atom: { result = MD_I64FromString(expr->node->string, 10); }break; + case MD_C_ExprKind_Atom: { + result = MD_CStyleIntFromString(expr->node->string); + }break; default: break; } return result; diff --git a/source/md_impl.c b/source/md_impl.c index c96580f..b2c91cb 100644 --- a/source/md_impl.c +++ b/source/md_impl.c @@ -424,43 +424,81 @@ MD_JoinStringList(MD_String8List list, MD_String8 separator) return string; } -MD_FUNCTION_IMPL MD_i64 -MD_I64FromString(MD_String8 string, MD_u32 radix) +MD_FUNCTION_IMPL MD_u64 +MD_CalculateCStringLength(char *cstr) +{ + MD_u64 i = 0; + for(; cstr[i]; i += 1); + return i; +} + +MD_FUNCTION_IMPL MD_u64 +MD_U64FromString(MD_String8 string, MD_u32 radix) { MD_Assert(2 <= radix && radix <= 16); - static MD_u8 char_to_value[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, }; - - // get the sign - MD_i64 sign = +1; - MD_u64 i = 0; - if (string.size > 0){ - if (string.str[i] == '-'){ - i = 1; - sign = -1; - } - if (string.str[i] == '+'){ - i = 1; - } - } - - // get the value - MD_i64 value = 0; - for (;i < string.size; i += 1){ + MD_u64 value = 0; + for (MD_u64 i = 0; i < string.size; i += 1){ value *= radix; MD_u8 c = string.str[i]; value += char_to_value[(c - 0x30)&0x1F]; } - value *= sign; - return(value); } +MD_FUNCTION_IMPL MD_i64 +MD_CStyleIntFromString(MD_String8 string) +{ + MD_u64 p = 0; + + // consume sign + MD_i64 sign = +1; + if (p < string.size){ + MD_u8 c = string.str[p]; + if (c == '-'){ + sign = -1; + p += 1; + } + else if (c == '+'){ + p += 1; + } + } + + // radix from prefix + MD_u64 radix = 10; + if (p < string.size){ + MD_u8 c0 = string.str[p]; + if (c0 == '0'){ + p += 1; + radix = 8; + if (p < string.size){ + MD_u8 c1 = string.str[p]; + if (c1 == 'x'){ + p += 1; + radix = 16; + } + else if (c1 == 'b'){ + p += 1; + radix = 2; + } + } + } + } + + // consume integer "digits" + MD_String8 digits_substr = MD_StringSkip(string, p); + MD_u64 n = MD_U64FromString(digits_substr, radix); + + // combine result + MD_i64 result = sign*n; + return(result); +} + MD_FUNCTION_IMPL MD_f64 MD_F64FromString(MD_String8 string) { @@ -474,14 +512,6 @@ MD_F64FromString(MD_String8 string) return(atof(str)); } -MD_FUNCTION_IMPL MD_u64 -MD_CalculateCStringLength(char *cstr) -{ - MD_u64 i = 0; - for(; cstr[i]; i += 1); - return i; -} - MD_FUNCTION_IMPL MD_String8 MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 separator) { @@ -2651,7 +2681,7 @@ MD_CommandLineOptionI64(MD_CommandLine cmdln, MD_String8 name) MD_i64 v = 0; MD_String8List values = MD_CommandLineOptionValues(cmdln, name); MD_String8 value_str = MD_JoinStringList(values, MD_S8Lit("")); - v = MD_I64FromString(value_str, 10); + v = MD_CStyleIntFromString(value_str); return v; }