Hey! I'm willing to create a programming language using nim.
It's an educational project. Been reading about compilers for weeks now and I started using tools like flex and bison for lexer and parser. I know nim have a parsing library but nowhere near that level.
There is an old post (2014) with a similar question so I'm bringing that back a few years later. Is there anything anyone know that could speed up the process of developing a programing language using nim? (I can have c code if needed ofc)
Wow, I was just reading about the compilation pipeline today!
I suppose you could use at least the lexing part from a generator like flex, not so sure about using AST generators easily (it's possible).
Is your language complicated enough to warrant a parser generator or could you just use a custom parser?
For educational project, parse it by hand :P
Parser for s-expression like Lisp families are easy to write :D
Afaik, there's no lib in Nim specifically for that tho.
Here are a few resources:
The JSON module: https://github.com/nim-lang/Nim/blob/master/lib/pure/json.nim#L150
The lexbase module: https://nim-lang.org/docs/lexbase.html
Spry-lang, a Smalltalk/Rebol like language written in Nim. It leverages Nim lexer and operates directly on Nim AST.
PMunch also has a lot of parsers in his repo but I think binary parsers only: https://github.com/PMunch?tab=repositories
Basically Nim object variant (kind objects) are your best friends.
For educational project, parse it by hand
For educational and serious project, parse it by hand (Nim parser is handwritten, as is GCC, Clang, MSVC, FPC, OpenJDK, Golang and many others). Use tools only for quick and dirty one 😉
Is it really that worth to lex and parse by hand?
I've sent you an email @cabhishek!
@cabhishek,
I'm wondering if you could explain a couple things in your lox interpreter code.
For example, sometimes you pass lexer as a var, sometimes not.
proc peek(lex: var Lexer): char
proc isAtEnd(lex: Lexer): bool
Could you explain a little about this slight difference?
I've been doing something similar for the
lang, following:
://interpreterbook.com/
In the Lox resource, the author uses Java as the implementation lang. For Monkey the author uses Go - a classless lang like Nim.
But in Go the author passes a pointer to the Lexer in order manipulate/modify state in the lexer.
In your code I see Lexer is simply an object, not a ref object or a ptr.
Does defining the parameter as proc(lex: var Lexer) behave similar to a pointer? This has the result of mutating state in the Lexer object? In other words, it's like passing by reference rather than by value?
Another question, do you intend to experiment converting the Lox AST to Nim AST and as a result have it become a compiled language rather than an interpreted one?
I haven't read that https://interpreterbook.com but I've read this instead http://buildyourownlisp.com free to read for html version
From the name, it should be obvious that peek manipulate the line, taking out the next char while the cursor position is still at it is. Hence its signature proc (lex: var Lexer): char
Does defining the parameter as proc(lex: var Lexer) behave similar to a pointer? This has the result of mutating state in the Lexer object? In other words, it's like passing by reference rather than by value?
Yes
Read @yglukhov informational post on choosing object and/or ref object https://forum.nim-lang.org/t/3869#24100
I know I had nothing to do with the original post but I'll chime in for some quick answers.
Here's the manual entry about var parameters. It seems to me like you understand what they are but just in case here's a simple example with the basic int type.
proc foo(a: var int) =
a = 10
var x = 7
foo(x)
echo x # 10
Objects are immutable out of scope, for example if you pass them to non-var proc arguments you can't change their properties in the proc, so you'd have to use var parameters. This isn't the case with ref/ptr objects though, as you mentioned.
You don't have access to Nim AST at runtime, so you would have to use the Nim compiler as an API with the compiler nimble package. You do need to know a little bit about the compiler to do this, however.