Loci v1.4 Released

The latest version of the Loci compiler is now available. See the release notes for detailed information about what’s included.

The main feature in this release is a brand new compiler diagnostics system with a rewritten lexer and parser. Here’s an example of errors from the old compiler:

Parser Error: Failed to parse file 'MultipleElse.loci' with 2 errors:
Parser Error (at SourceLocation(filename = MultipleElse.loci, range = (line 11, column 4) to (line 11, column 8))): syntax error, unexpected ELSE
Parser Error (at SourceLocation(filename = MultipleElse.loci, range = (line 11, column 4) to (line 11, column 8))): Invalid statement.

And here’s how it looks with the new diagnostics system:

MultipleElse.loci:11:4: error: 'else' without a previous 'if'
  } else {
    ^~~~
1 error generated.

This release is therefore an enormous improvement in the usability of the compiler and the cause of errors/warnings should be very clear to the user.

atoi() vs std::stringstream

I was recently asked to compare the functionality of atoi() and std::stringstream.

Here’s the code:

#include <stdio.h>
#include <stdlib.h>
#include <sstream>

void strToInt(const char* str) {
    {
        // Set to garbage value.
        int val = 479894;

        std::stringstream stream;
        stream << str;
        stream >> std::dec >> val;
        printf("stream: '%s' -> %d\n", str, val);
    }

    {
        const int val = atoi(str);
        printf("atoi: '%s' -> %d\n", str, val);
    }

    printf("\n");
}

int main() {
    strToInt("");
    strToInt("0");
    strToInt("a");
    strToInt("1");
    strToInt("44a");
    strToInt("a44");
    return 0;
}

And here’s the output:

stream: '' -> 479894
atoi: '' -> 0

stream: '0' -> 0
atoi: '0' -> 0

stream: 'a' -> 0
atoi: 'a' -> 0

stream: '1' -> 1
atoi: '1' -> 1

stream: '44a' -> 44
atoi: '44a' -> 44

stream: 'a44' -> 0
atoi: 'a44' -> 0

So it looks like the functionality of both is actually very similar (though note std::stringstream has many ways to modify its behaviour); unfortunately it seems the stream doesn’t set the result to zero when given an empty string.