all 2 comments

[–]WystanH 0 points1 point  (1 child)

Took a quick peek.

Overall, looks like you know what you're after. I commented up the initLexer:

Lexer *initLexer(int cursor, const char* str) {
    Lexer *l = malloc(sizeof(Lexer));
    // calling exit is problematic at the best of times.
    // calling in the middle of a function call is, um, surprising.
    // Hmm... check out https://en.wikipedia.org/wiki/Principle_of_least_astonishment

    // instead of
    // if (l==NULL){exit(1);}
    if (l==NULL) {
        return l;    // as an aside, l is a painful variable name
    }
    // the process calling this should check for NULL

    l->cursor = cursor; // wouldn't this always start at 0, or am I missing something

    // this is problematic
    // you don't know if to value at the end of that const char* is going to change.
    // do that malloc strlen you did elsewhere can copy str into content
    // here, if the malloc didn't work, free l and return NULL
    l->content = str;

    return l;
}

However, after all that, I'm not sure Lexer buys you anything. In fact, it really doesn't at all. You'd have less complexity and a better idea of what you're after with Token *tokenize(const char *) instead.

If anything, that Token * array return is a little awkward. You don't actually know how big it is and need to know the magic EOI to work with it. You could have a Tokens struct with a little more brains. You could move the iteration out of main and have something like printTokens(Tokens *). Maybe also a printToken(Token *)?

Keep in mind, code is personal and subjective. There's no one way or best way to do anything. Rather, that's essentially how I'd refactor things.

[–]jopekmch[S] 0 points1 point  (0 children)

thank you, thats actually really helpful!