diff --git a/calc.c b/calc.c new file mode 100644 index 0000000..7505803 --- /dev/null +++ b/calc.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +typedef enum { + LITERAL, + ADD, + SUB, + MUL, + DIV, +} ExprKind; + +struct Expr; + +typedef struct { + struct Expr *lhs; + struct Expr *rhs; +} BinOp; + +typedef struct { + ExprKind tag; + union { + int64_t literal; + BinOp op; + } value; +} Expr; + +bool is_numeric(const char character) { + return character >= '0' && character <= '9'; +} + +void parse_expr(char *input, size_t *offset) { +} + +void parse_factor(char *input, size_t *offset) { +} + +void parse_term(char *input, size_t *offset) { +} + +Expr parse_literal(char *input, size_t *offset) { + // the index of the first character of the literal + const size_t start = *offset; + + // the index of the character past the last character of the literal + size_t end = start; + + while (input[*offset] != '\0' && is_numeric(input[*offset])) { + (*offset)++; + end = *offset; + } + + size_t literal_len = end - start; + + if (literal_len == 0) { + fprintf(stderr, "Found end of file expecting number"); + exit(1); + } + + // because C standard library functions are utterly deranged and want null terminated strings, we have to hack a little + // just set the next character to null to get a nice null terminated string + char old_next_char = input[literal_len]; + + int64_t value = strtoll(input + start, NULL, 10); + + // and then don't forget to set it back :D + input[literal_len] = old_next_char; + + Expr expr; + expr.tag = LITERAL; + expr.value.literal = value; + + return expr; +} + +int main(int argc, char **argv) { + if (argc == 1) { + printf("provide me an argument please\n"); + return 1; + } + + char *input = argv[1]; + + size_t offset = 0; + + Expr expr = parse_literal(input, &offset); + + printf("%ld\n", expr.value.literal); + + return 0; +} diff --git a/main.c b/main.c deleted file mode 100644 index 601aec7..0000000 --- a/main.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include - -typedef enum { - LITERAL - ADD - SUB - MUL - DIV - GROUP -} expr_kind; - -typedef struct { - expr_kind tag; - union { - - } value; -} expr; - -int main(int argc, char **argv) { - if (argc == 1) { - printf("provide me an argument please\n"); - return 1; - } - - char *input = argv[0]; - - return 0; -} - -int parse_expr(char *input, size_t *offset) {} - -int parse_factor(char *input, size_t *offset) {} - -int parse_term(char *input, size_t *offset) {} - -int parse_literal(char *input, size_t *offset) {}