tokenate() and reverse_list_in_place()

This commit is contained in:
Simon Forman 2023-03-04 17:23:54 -08:00
parent dfd8f86e7b
commit 9cde4ed73d
1 changed files with 104 additions and 10 deletions

View File

@ -157,6 +157,78 @@ char* RIGHT_BRACKET_symbol = "]";
u32 LEFT_BRACKET; u32 LEFT_BRACKET;
u32 RIGHT_BRACKET; u32 RIGHT_BRACKET;
bool
is_integer(char *str, u32 index, u32 length)
{
for (;length; --length) {
char ch = *(str + index + length - 1);
if (!(ch == '0'
|| ch == '1'
|| ch == '2'
|| ch == '3'
|| ch == '4'
|| ch == '5'
|| ch == '6'
|| ch == '7'
|| ch == '8'
|| ch == '9'))
{
return 0;
}
}
return 1;
}
u32
convert_integer(char *str, u32 index, u32 length)
{
u32 result = 0;
length = length + index;
for (; index < length; ++index) {
char ch = *(str + index);
u8 digit = (u8)ch - (u8)'0';
result = result * 10 + digit;
}
print_str("converted integer ");print_i64(result);print_endl();
return JOY_VALUE(joyInt, result);
}
u32
tokenate(char *str, u32 index, u32 length)
{
if (4 == length
&& *(str + index) == 't'
&& *(str + index + 1) == 'r'
&& *(str + index + 2) == 'u'
&& *(str + index + 3) == 'e'
) {
print_str("tokenate true");print_endl();
return JOY_VALUE(joyBool, 1);
}
if (5 == length
&& *(str + index) == 'f'
&& *(str + index + 1) == 'a'
&& *(str + index + 2) == 'l'
&& *(str + index + 3) == 's'
&& *(str + index + 4) == 'e'
) {
print_str("tokenate false");print_endl();
return JOY_VALUE(joyBool, 0);
}
if (is_integer(str, index, length)) {
print_str("tokenate integer");print_endl();
return convert_integer(str, index, length);
}
// TODO: Convert bools and ints here?
// Use ht_insert to avoid multiple allocations of the same string!
char *token = allocate_string(str, index, length);
if (!token)
return 0; // OOM
return JOY_VALUE(joySymbol, ht_insert(token));
}
u32 u32
tokenize0(char *str, u32 str_length, u32 index, u32 acc) tokenize0(char *str, u32 str_length, u32 index, u32 acc)
@ -188,13 +260,7 @@ tokenize0(char *str, u32 str_length, u32 index, u32 acc)
} }
} }
// i == str_length OR str[i] is a delimiter char. // i == str_length OR str[i] is a delimiter char.
return cons(tokenate(str, index, i - index), tokenize0(str, str_length, i, acc));
// TODO: Convert bools and ints here?
// Use ht_insert to avoid multiple allocations of the same string!
char *token = allocate_string(str, index, i - index);
if (!token)
return 0; // OOM
return push_symbol(token, tokenize0(str, str_length, i, acc));
} }
@ -205,6 +271,33 @@ tokenize(char *str)
return tokenize0(str, strlen(str), 0, empty_list); return tokenize0(str, strlen(str), 0, empty_list);
} }
u32
rev(u32 el, u32 end)
{
u32 t = tail(el);
tails[el] = end;
if (t) {
return rev(t, el);
}
return el;
}
u32
reverse_list_in_place(u32 el)
{
if (!el) { // Empty list.
return el;
}
u32 t = tail(el);
if (!t) { // Length-one list.
return el;
}
// Re-write tails[el] to point to null
tails[el] = empty_list;
// reverse the tail of this list and prepend it to [el].
return rev(t, el);
}
u32 stack[1000]; u32 stack[1000];
u32 stack_top = 0; u32 stack_top = 0;
@ -229,13 +322,13 @@ text_to_expression(char *str)
} }
if (RIGHT_BRACKET == tok) { if (RIGHT_BRACKET == tok) {
print_str("right bracket");print_endl(); print_str("right bracket");print_endl();
tok = frame; // as list tok = reverse_list_in_place(frame);
frame = stack[stack_top]; frame = stack[stack_top];
--stack_top; --stack_top;
} }
frame = cons(tok, frame); frame = cons(tok, frame);
} }
return frame; // as list; return reverse_list_in_place(frame);
} }
@ -283,7 +376,8 @@ main()
/*print_str(allocate_string(buffer, 4, 4)); print_endl();*/ /*print_str(allocate_string(buffer, 4, 4)); print_endl();*/
/*print_str(allocate_string(buffer, 2, 4)); print_endl();*/ /*print_str(allocate_string(buffer, 2, 4)); print_endl();*/
/*print_str(allocate_string(buffer, 7, 5)); print_endl();*/ /*print_str(allocate_string(buffer, 7, 5)); print_endl();*/
u32 jv = text_to_expression(" 1 [2 3] 3[4]5"); u32 jv = text_to_expression(" 1 [2 true 3 bob]false bob 3[4]5");
jv = reverse_list_in_place(jv);
if (LEFT_BRACKET == jv) { if (LEFT_BRACKET == jv) {
print_str("boo"); print_str("boo");
} else { } else {