Built this because every image optimizer I found was either slow, bloated, or a subscription. Squish takes a folder of images, compresses them, done.
~4400 lines of C++, no dependencies, custom JPEG encoder with AVX2 (scalar fallback for older CPUs), threaded, atomic writes. 77-95 MB/s on 6 cores.
Had to harden it pretty hard after the first version would have crashed on any machine without AVX2. Now handles OOM, symlink loops, path traversal, the works. MIT licensed, happy to answer questions
Hey, I made this because I kept waiting forever when parsing server logs at work. Tried a few tools, they were all slow as hell, so I figured I'd see how fast I could get it.Turns out if you skip the usual file reading stuff and just mmap the file directly, then throw some AVX2 SIMD at the character counting, things get pretty quick. Getting around 1.4 GB/s on my NVMe which is like 77% of what the SSD can actually do. Rest is just OS overhead and page faults.
It falls back to SSE2 on older CPUs so it should run on pretty much anything. Works on Windows and Linux.
Anyway, let me know if you have questions about how it works or ideas for improvements
Thanks, that's fair criticism.
You're right about the while-loop thing, that code was very naive and did break with nesting. I actually ran into exactly the pain you described and ended up fixing it the hard way. It was one of the moments where I realized how quickly you start fighting the architecture instead of working on the language itself.
About the bigger point: I agree with you, and that's kind of the direction I'm drifting towards now. I'm not really interested in competing with Zig feature-for-feature. What I'm more interested in is whether there's a different mental model for system programming that feels simpler. I originally planned to add pointers, but they gave me massive headaches. That was exactly the point where "low-level" and "simple" started to completely collide in my brain. The more I tried to make pointers feel clean, the more complex everything became.
So the current idea I'm exploring is: what if you could write system-level code without having to think in memory addresses at all, but still keep things explicit and predictable? More like thinking in values and state changes, instead of locations in memory. That's still very much an experiment, but that's the "missing opinion" I'm trying to test
I totally agree. "Python-like" was a bad choice of words on my part. I meant it more in terms of learning curve and explicitness, not the surface syntax. Structurally its more like C/Rust and I should have said that from the start
Yes, I used AI during development. I treated it as an assistant for explanations, brainstorming, and occasional small code snippets. The language design, compiler architecture, semantics, and the majority of the implementation were written and decided by me
Right now there’s intentionally no stdlib, so yes, printing would ultimately boil down to a direct write syscall. The idea is that the core language stays as thin as possible and anything higher level lives on top of that, either as compiler intrinsics or a very small stdlib later. For the MVP I wanted to make the boundary explicit instead of pretending there’s no syscall underneath. So “Hello world” will work, but in a very boring, low level way at first
Yeah that's fair. It's got "fn main()", types like "i32", and uses braces. More Rust-like than Python to be honest. The "Python-like" part is mostly wishful thinking about readability. Should've just called it "minimalist systems language" or something
Indent-based syntax is relatively simple to parse. You basically need two pieces of state: are you in indent-sensitive mode (not inside a literal, not inside a parenthesized expression), and what indentation did the previous line have. Then you can easily issue INDENT and DEDENT tokens, which work exactly like "{" and "}". The actual Python parser does issue these tokens.
Actually Haskell has both indent-based and curlies-based syntax, and curlies freely replace indentation, and vice versa (but only as pairs).
That’s enough for INDENT, but for DEDENT you also need a stack of previous indentation levels. That’s how, when the amount of indentation decreases, you know how many DEDENTs to emit.
The requirement for a stack means that Python’s lexical grammar is not regular.
Yeah braces made the parser way simpler for a first attempt. Significant whitespace is on the maybe-list but honestly seems scary to implement correctly
I feel like Python-style indentation should be much easier to parse intuitively (preprocess the line, count leading levels of indentation) than by fully committing to formal theory. Not theoretically optimal and not "single-pass" but is that really the bottleneck?
Yeah, that’s fair. Conceptually it’s not that hard if you’re willing to do a proper preprocess pass and generate INDENT and DEDENT tokens. For this first version I mostly optimized for not shooting myself in the foot, braces gave me very explicit block boundaries, simpler error handling, and a much easier time while bringing up the compiler and codegen. Significant whitespace is definitely interesting long term, but for a v0 learning project I wanted something boring and robust first. Once the core stabilizes, revisiting indentation based blocks would make a lot more sense
Might I suggest that now is a good time to try and make a concrete wish-list of syntax features you'd like to see, and start drafting examples of how you'd like the code to look?
I built AXIS as a learning project in compiler design. It compiles directly to x86-64 machine code without LLVM, has zero runtime dependencies (no libc, direct syscalls), and uses Python-like syntax.
Currently Linux-only, ~1500 lines of Python. All test programs compile and run. The one-line installer works: curl -fsSL https://raw.githubusercontent.com/AGDNoob/axis-lang/main/ins... | bash
It's very early (beta), but I'd love feedback on the design and approach!