You are browsing as a guest. Sign up (or log in) to start making projects!

Ile

  • 13 Devlogs
  • 58 Total hours

Ile is an Interpreted Language for Extensions. It's an embedded scripting language with a Rust API. Oh, and it has no 3rd-party dependencies!

Ship #1 Pending review

I made Ile, an embedded scripting language! It uses a recursive descent parser to build an abstract syntax tree and then walks the tree to execute. The hardest part was when I would run into tiny little problems, like Rust giving lifetime errors, and not knowing how to solve them immediately. I’m proudest of the parsing logic. It’s the longest source file I’ve ever written, and it took awhile to figure out.

To test Ile, you can download it from the GitHub releases and run some of its example programs.

  • 13 devlogs
  • 58h
Try project → See source code →
Open comments for this post

5h 5m logged

Devlog 13: Ship time!

I’ve been working on getting everything ready to ship, and I think it’s almost time! I’ve fixed some bugs, added more tests, published to crates.io, and created a GitHub release! Now, I’ll make sure I have good instructions in my README, and I’ll be ready to go!

0
0
6
Open comments for this post

5h 31m 48s logged

Devlog 12: Scoping is hard

I’ve been working on getting Ile ready to ship, and I had a small, significant feature to implement: scoping. This is basically when a function is called and uses the scope that it was a part of when it was created instead of the scope it was called in. This was hard.

To implement this, my first thought was write yet another lookup function to find the correct module’s stack and walk the function in the stack. Unfortunately, the compiler didn’t like this. I couldn’t get it done without having 2 different mutable references to the stack at the same time, so it was off the table. What I ended up going for was when a function is called, it clones (memory-efficient, amirite?!) its entire scope and walks inside it. After the function executes, it then sets the value of its module’s scope to the current value of the scope it just walked in, so as to update it with any changes. Makes sense, right? RIGHT?!

Anyway, there isn’t really a picture to show, so here’s tests passing.

0
0
4
Open comments for this post

4h 20m 31s logged

Devlog 11: I don’t even know

I’m hoping to ship tomorrow, so I’m fixing up the language to be usable. I’ve been writing some documentation, so I have a little starter guide now. I also learned that Ile can use as little as one thirtieth the ram of Node.js! That’s definitely going in the features section.

0
0
12
Open comments for this post

5h 21m 10s logged

Devlog 10: asdf

I’ve been trying to add a GUI system to the standard library. Because I don’t want any dependencies, I came up with the following harebrained scheme:

  • Write a Python script that formats its stdin in a Tkinter window to draw a GUI
  • When the function to create a window is called, spawn Python as a sub-process and send the text to be displayed to its input via a pipe

Unfortunately, this doesn’t work. The script works when run on its own, but when run by Ile it just doesn’t launch a window. I couldn’t figure this out, so the GUI system (VeBaGu, or Very Bad GUI) is staying, albeit in an unstable beta state.

On a side note, I’ve also decided to ditch the editor idea and just focus on the language; this Stardance project is now just Ile, not Crocodile.

0
0
12
Open comments for this post

1h 33m 28s logged

Devlog 9: Hello, world!

I didn’t do that much work for this devlog, but I did achieve 2 important things:

  • Added comment support
  • Added bindings to println!() and stdin
    This means that Ile, as demonstrated below, can now read its stdin and write to stdout!
0
0
5
Open comments for this post

5h 23m 28s logged

Devlog 8: We have language!

If you couldn’t tell, that was a play on “we have liftoff!”. I didn’t add a rocket emoji, for obvious reasons.

Anyway, I have great news: Ile is almost a usable language! Today, I added loops and operators, so it can iterate and do math now! My for loop is a tad different than other languages, so here’s the gist: every for loop has a condition and a block. Every iteration, the condition runs. If it returns something, the block runs. Otherwise, the loop exits. Because I made let statements return the value they assign, you can have syntax that looks like this:

for let x = iterator.next() {}

I’m really proud of how my syntax is turning out overall. There’s still not much to screenshot; I haven’t written the logic to interface with Rust, so there’s no println yet. I do have some more test coverage, though.

There was some difficulty getting break to work, however. For some reason, the loop it was a part of would always keep going. Eventually, I figured out why: It was being removed from the stack at the end of the code block that generated it. To fix this, I added some logic to re-push it to the stack if it got popped.

0
0
3
Open comments for this post

4h 1m 20s logged

Devlog 7: Running before I can run

For some reason, I felt like instead of finishing the syntax fundamentals, I would skip directly to object-oriented (ish) patterns. In this case, we have a bunch of attributes that can be accessed and modified.

Below is a snippet of some OOP concepts in practice:

0
0
15
Open comments for this post

2h 40m 33s logged

Devlog 6: {insert dark joke about lifetimes}

I just spent a frustratingly long amount of time figuring out why Rust didn’t like my lifetimes. I don’t even remember what I did to make it compile. This was fun.

However, after figuring that out, I wrote the walk methods for a few NodeTypes. Here’s the stack after a simple program finishes, and the program that was run:

0
0
8
Open comments for this post

3h 30m 18s logged

Devlog 5: Operators

I started work on the AST (abstract syntax tree) walking algorithm today. I didn’t get very far, but one of the things I did do was I fixed operator parsing.

Before, if you were to parse something like 15 > 5 && 5 < 10, it would have been a greater-than operator with a boolean operator as a child, and that doesn’t work. Therefore, I had to write some code to convert that broken operator into a boolean operator with mathematical children. The algorithm didn’t make much sense in my head, so I drew it out on paper and that made it pretty easy to write.

Below is the illustration I made and the code it became.

1
0
32
Open comments for this post

3h 46m 34s logged

Devlog 4: I finished the parser!

I wrote the parser, which takes the tokenized code and converts it into a usable, in-memory representation. After fixing the bugs from yesterday, I wrote some logic to parse a function block and the rest of the syntax was easy. Running main.rs now prints out a representation of a parsed AST. Now all I have to do is:

  • make the AST walkable, so I can actually execute the code
  • write logic to facilitate interop with Rust

The first image is some example Ile code, and the second is some of the AST that is generated from it.

0
0
8
Open comments for this post

7h 50m 5s logged

Devlog 3: An almost-broken parser!

I made a very basic AST parser! The AST (abstract syntax tree) is the in-memory representation of the code as a tree. This took a really long time. My machine froze and my interpreter produced incomprehensible errors about wanting a word token, but in the end cargo test passed, so I’m happy.

It also doesn’t support anything other than function calls, but this is a great first step in creating an actually walkable AST.

0
0
8
Open comments for this post

1h 46m 40s logged

Devlog 2

I started work on the AST builder. I decided that the algorithm will use delimiters to decide which tokens correspond to which AST node and I’m working on a method for Node that determines how to add a child based on the Node‘s type and the child’s type.

The screenshot is some of the code for Node.

0
0
9
Open comments for this post

7h 5m 31s logged

Devlog 1: Building blocks

I’ve been focusing on the scripting language, Ile, because to be honest the editor is the boring part. So far, I have project structure and some fundamentals–I’ve written the tokenizer and some stack-switching logic. For those who don’t know, the tokenizer is responsible for taking a blob of (hopefully) human-readable source code and converting it into tokens, which are used later on to build an abstract syntax tree. For now, all I’m concerned about is that cargo test passes!

0
0
7

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…