Pairs are 2-tuples of values that are constructed and matched with the `::`
operator. They can also be matched with a `:` operator, the LHS is an
expression then, the pair will then only match, if the LHS matches the
result of that expression.
Pairs should be useful to do something similar what sum types / tagged
unions do in statically typed languages, e.g. you could write something
like:
some := (symbol) # Somthing that creates a unique value
filter-map := {
_ [] -> []
f [x ~xs] ->
{
some:y -> [y ~(filter-map f xs)]
nil -> filter-map f xs
} (f x)
}
filter-map {
x?even -> some :: (* x 10)
_ -> nil
} some-list
127 lines
2.9 KiB
C
127 lines
2.9 KiB
C
#include <inttypes.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "apfl.h"
|
|
|
|
static bool
|
|
has_text_data(enum apfl_token_type type)
|
|
{
|
|
switch (type) {
|
|
case APFL_TOK_NAME:
|
|
case APFL_TOK_STRING:
|
|
case APFL_TOK_COMMENT:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static bool
|
|
has_numeric_data(enum apfl_token_type type)
|
|
{
|
|
switch (type) {
|
|
case APFL_TOK_NUMBER:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void
|
|
apfl_token_deinit(struct apfl_allocator allocator, struct apfl_token *token)
|
|
{
|
|
if (has_text_data(token->type)) {
|
|
apfl_string_deinit(allocator, &token->text);
|
|
}
|
|
}
|
|
|
|
const char *
|
|
apfl_token_type_name(enum apfl_token_type type)
|
|
{
|
|
switch (type) {
|
|
case APFL_TOK_LPAREN:
|
|
return "(";
|
|
case APFL_TOK_RPAREN:
|
|
return ")";
|
|
case APFL_TOK_LBRACKET:
|
|
return "[";
|
|
case APFL_TOK_RBRACKET:
|
|
return "]";
|
|
case APFL_TOK_LBRACE:
|
|
return "{";
|
|
case APFL_TOK_RBRACE:
|
|
return "}";
|
|
case APFL_TOK_MAPSTO:
|
|
return "->";
|
|
case APFL_TOK_EXPAND:
|
|
return "~";
|
|
case APFL_TOK_DOT:
|
|
return ".";
|
|
case APFL_TOK_AT:
|
|
return "@";
|
|
case APFL_TOK_SEMICOLON:
|
|
return ";";
|
|
case APFL_TOK_LINEBREAK:
|
|
return "LINEBREAK";
|
|
case APFL_TOK_CONTINUE_LINE:
|
|
return "\\";
|
|
case APFL_TOK_COMMENT:
|
|
return "COMMENT";
|
|
case APFL_TOK_COMMA:
|
|
return ",";
|
|
case APFL_TOK_QUESTION_MARK:
|
|
return "?";
|
|
case APFL_TOK_STRINGIFY:
|
|
return "'";
|
|
case APFL_TOK_ASSIGN:
|
|
return "=";
|
|
case APFL_TOK_LOCAL_ASSIGN:
|
|
return ":=";
|
|
case APFL_TOK_NUMBER:
|
|
return "NUMBER";
|
|
case APFL_TOK_NAME:
|
|
return "NAME";
|
|
case APFL_TOK_STRING:
|
|
return "STRING";
|
|
case APFL_TOK_COLON:
|
|
return ":";
|
|
case APFL_TOK_DOUBLE_COLON:
|
|
return "::";
|
|
}
|
|
|
|
return "(unknown token)";
|
|
}
|
|
|
|
void
|
|
apfl_token_print(struct apfl_token token, FILE *file)
|
|
{
|
|
if (has_text_data(token.type)) {
|
|
fprintf(
|
|
file,
|
|
"%s (" APFL_STR_FMT ") @ (%" PRIuMAX ":%" PRIuMAX ")\n",
|
|
apfl_token_type_name(token.type),
|
|
APFL_STR_FMT_ARGS(apfl_string_view_from(token.text)),
|
|
(uintmax_t)token.position.line,
|
|
(uintmax_t)token.position.col
|
|
);
|
|
} else if (has_numeric_data(token.type)) {
|
|
fprintf(
|
|
file,
|
|
"%s (%f) @ (%" PRIuMAX ":%" PRIuMAX ")\n",
|
|
apfl_token_type_name(token.type),
|
|
token.number,
|
|
(uintmax_t)token.position.line,
|
|
(uintmax_t)token.position.col
|
|
);
|
|
} else {
|
|
fprintf(
|
|
file,
|
|
"%s @ (%" PRIuMAX ":%" PRIuMAX ")\n",
|
|
apfl_token_type_name(token.type),
|
|
(uintmax_t)token.position.line,
|
|
(uintmax_t)token.position.col
|
|
);
|
|
}
|
|
}
|