Open comments for this post
New project alert!
Iāve started working on an app called āThermalsā. It serves the purpose of being a simple yet modern and elegant usage and temperature monitor, accessible through a tray icon, made to work on both Windows and Linux.
Current Progress
Build System, Repository and similar is set up and simple tray icon (a white square) is also working.
Looking forward to how this project comes out! :)
Open comments for this post
Whoops
Had a small bug in the left arrow key in normal editing mode and popups werenāt resizing and re-positioning correctly, fixed all that :)
FINAL RELEASE BABYYYY (hopefully)
Open comments for this post
Finally, the debugger is working properly.
If youāve tried a beta version, especially v1.1.0, you might have noticed the debugger being broken and kinda weird. I noticed that too, so I decided to rewrite it!
(technically, I rewrote it twice but oh well)
Why it needed a rewrite
Before, the debugger worked by executing the next step in-place and jumping in loops by moving the cursor to the matching bracket.
The problem was: to jump backwards when looping, you had to keep a history which could pretty quickly get filled if you were debugging enough and overall the system was too overengineered for what it was supposed to do.
The new architecture
The new debugger does almost the same that the live tape preview already does. The live tape preview has one caveat that doesnāt allow it to be directly used for the debugger though: we cannot track loop iterations on the cursor position alone, as we always just compute until the cursor. If weāre before a loopās end, weāre only computing the first iteration. If we move past the loop, the whole loop gets computed in one move.Instead of the cursor pos, the debugger uses an instruction counter. It basically counts how many brainf*ck instructions it should run, which solves all problems here.
Why this works
Take this program:
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
Say we wanna run 40 instructions. We first step over the initial ++++++++[>++++[>++>+++>+++>+<<<<- (33 instructions), and then we get to the first ].
When we do, the current cell is non-zero, meaning we jump back to the instruction after the highlighted bracket (++++++++[>++++ [ >++>+++>+++>+<<<<-).
The jump is one instruction. Then we run >++>++ and reach 40. Notice how weāre in the second iteration when it ends. If we now move the cursor forward by one, we tell the tape generator āexecute 41 instructionsā.
The same as before happens now (execute first bit, jump back, continue executing - but one instruction more than before this time) but we land in the second iteration again.
Open comments for this post
Popups are finished! (almost)
After a little bit of work, a popup system (which I gotta say is written kinda well compared to all the other code) is in place!
Currently, there are:
- Exit Confirmation Popup
- Save File Dialog
- Load File Dialog
One last thing is still missing though: The please press a button popup for inputs (,).
Technical Details
The popup system works by using a sub-struct inside of the global state struct (state.popup). It contains data such as whether a popup is active, if it accepts text input and handlers for drawing and the confirm button.
Ā
Thereās a base func (create_popup_base()) that draws a new basic outline for the popup. After that, only the contents of the popup get refreshed via the custom handler set via setting a function pointer (state.popup.refresh_handler).
The popup also ācapturesā input. Thereās a seperate if for state.popup.active before the main input validation which processes inputs and then skips the normal input processing.
Open comments for this post
The debugger works!!
After hours of work (mainly debugging and patching up code), it finally works! :DD
The power of the debugger
You can use the debugger to step forward and backward in your brainf*ck program. While stepping, a live program counter display (labelled āPCā) shows the current program counter index, while the tape in the bottom panel shows the current state of each cell, which cell is currently selected by the data pointer and what the cell contains, in both decimal and ASCII format.
The following is just for if youāre interested in the technical details ;)
Why I wanted to wipe my drive several times while making this (Problem 1)
The first main problem in writing the debugger was stepping backward. Youād think its just ādo the instruction in reverse, like when you back-step a -, just do a + insteadā but the problem arises when, for example, you read in something using , and the info got overwritten. How do you reverse to something that got destroyed? Well, you donāt.
The Solution to the Back-Stepping problem
I implemented backward stepping by just recomputing the entire tape from scratch on every backstep. Yes, itās probably not the best way, but it works.
Problem 2
Loops. Once. Again.
The jumping around of loops in brainf*ck is not the simplest thing to correctly compute, especially when only partially executing a program.
When you land on a [ or a ], you also need to account for nested loops. You can probably imagine that that can definitely cause some headaches.
Open comments for this post
Live tape preview is done!
While writing or editing code or by literally just moving your cursor, you now get a live preview of the programs ātapeā (basically itās entire data it works with).
There is one big problem with the current system however. If youāre interested, feel free to read the following.
The big Issue
Loops. You see, in brainf*ck, loops work by using [ to jump to the matching ] if the current cell is zero and by using ] to jump to the matching [ if the cell is non-zero.
This behaviour is actually not that pleasant to simulate when youāre only executing to a specific point in the program, because the āsimulatorā (the thing that interprets the bit of brainf*ck code up until your cursor and then generates a tape from that) canāt see the matching closing ] as it comes after the cursor. This means the loop will never really execute. But, when you navigate past the entire loop block, the cells jump to a completely different state (as seen in the video at around 0:08).
How am I going to solve it then?
Iāve decided that I dont want to āsolveā it by somehow making loops work in live preview. Iāve decided live preview should only be relatively basic. For serious loop-involved debugging, I wanna introduce a special āDebug Modeā. In this mode, youāll be able to step through your code, have chars printed into the output panel live AND also have the cursor/program pointer correctly jump around.
Open comments for this post
Menubar Navigation, Code Running and Output Display works!! š :)
Today, the IDE ran its first program! (and yes, of course, it was a hello world program)
What changed?
As already mentioned in the last post, Iāve rewritten part of the menubar rendering and also implemented output field rendering. Also, Iāve refactored the run_brainfuck function to be compatible with the UI.
Changes in the run_brainfuck(...) function
Before, it just stubbornly printed to stdout and read from stdin which of course kinda conflicts with the UI. To solve this, I made it write into an output buffer and accept a function pointer for a function that needs to return an int of which char was read in. The actual reading in will be handled by the pointed to function, which will probably be a āPlease press a buttonā popup.
Whatās next
Looking forward to getting the tape reel and then popups (including file saving/loading, exit confirm and please press a button) to work!
Open comments for this post
Great News! The editor is now fully working!
Iāve managed to implement everything from syntax highlighting to special keys such as delete, home and end.
Nice! What now?
Iām also working on getting the menubar to work, whichāll require rewriting a little part of the menubar rendering, as currently, the text entries get printed in one go with the spaces. If I somehow wanna highlight the text only, I gotta draw it all seperately.
Open comments for this post
Typing works!! not
Another Memory Violation :)
Gonna debug that one too i guess
On the flip side, I got syntax highlighting working!
Open comments for this post
This was literally me after opening my code today
On a side note:
Iāve cleaned up the codebase a little and split stuff into separate files for readability, like moving the editor draw function along with all its helpers into a separate file.
Iām about to start working on finishing the editor panel now. :)
Open comments for this post
holy productivity spike
I got the editor fully working!!! :)
After wanting to throw my computer from a comically large height (multiple times), it finally runs: proper arrow-key navigation, a fully working cursor, soft wraps, line numbers, and so on. Vertical scrolling is now fully functional aswell.
Even some comfort features like using the Home and End keys work!
Fun stuff I found out in the process
In the process of getting this to work I also discovered things like the fact that the pdcurses getch() macro implicitly refreshes the stdscr and then⦠doesnt⦠flush it š
Anything still borked?
Some things also still donāt work fully, which kinda bothers me. The main example of this is navigating the cursor vertically into soft-wrapped lines; because of how I wrote the row up/down logic - which is to check in the editor buffer where the next or previous line feed is and then navigate based on that - I canāt just say āoh theres a soft line wrap lets just detect that instead of a \nā because the rendering (which does the soft line wrapping) and the I/O loop donāt communicate with each other
Sure, I could fix it by adding a shared data structure which contains all line wrappings, but for now, I just wanna get the more important stuff running.
Any plans now?
Anyways, Iām planning to finish the editor fully by adding writing text (wild concept, i know!) and syntax highlighting next.
Stay tuned to find out how much I continue to suffer! :ā)
Open comments for this post
No more Access Violation! Also, I managed to get the editor drawing going! :)
The interesting thing about the access violation fix is: I have no clue what caused it - it just kinda went away?? But oh well, the error is not happening anymore :D
Whats working now?
I so far mainly implemented colored line numbers and soft wrapping. The implementation for vertical scrolling however isnāt written yet, thatās the plan next. Also, Iāll probably implement cursor navigation with that in one go.
I also made some small optimizations to the main loop plus a few fixes and adjustments here and there.
Open comments for this post
I managed to prove why C is the most memory safe language that exists!!
This gets triggered by literally just resizing the window and I have zero idea why :ā)
On a side note though, Iāve been working on the editor panel a little and itās slowly coming together.
Anyways, looking forward to debugging hell for that one overflow or nullpointer (or whatever the hell this is)!
Open comments for this post
Panel borders are done and working! :D
How annonying was it?
The tricky part was getting the layout constants to line up correctly (it gets pretty annoying if youāre trying to find where you accidentally forgot to add one to a value)
Got there in the end though.
Anything else?
Also cleaned up the repo. I also added a git submodule so that PDCurses actually gets cloned too if you pass the --recurse-submodules when cloning.
Now the foundation is solid and I can actually start on the editor itself next session. :)
I also included a lil preview of how it looks rn :)
Open comments for this post
Introducing: Brainf*ck IDE - a TUI-based IDE for writing and running brainf*ck, built in C using PDCurses.
The IDE has a panelized layout: code editor on the left, output on the right, and a live tape viewer along the bottom so you can actually watch memory change in real time while writing code!
The screenshot is mocked up manually for now, the code for drawing doesnāt exist yet š
Whats already started
So far Iāve got the interpreter written and a few basic rendering steps working, including the top menubar.
How it works
The brainf*ck interpreter is actually really simple: you need a loop to iterate through a program buffer, then check for any āspecialā chars like <, +, ⦠and then just increment/decrement values or do some simple logic depending on which char it is.
Next, Iāll try to do the panel borders and some panel setup.
Looking forward to how much stuff will break! :)
Open comments for this post
Had a little fight with github actions and qemu wasm stuff.
Tried to implement a live web demo using a wasm implementation of qemu with UEFI and more, but couldnt get it to run.
Also, I heavily improved documentation and finished up the virtual memory manager (for nowā¦).
Plans?
Next, the heap allocator is coming then Iāll finally be able to use dynamic types!
was worth it i guess (it was not i gotta get up in 5h š„²)
Open comments for this post
Hi!
This is my āmainā project, āØFerriteOSāØ!
(Well, idk if you can call it a whole OS if im only planning to do a kernel, but anyways)
Ferrite is a Linux-ABI compatible kernel, written entirely in Rust, from scratch.
My goal
My end goal is for it to be able to run systemd, GNOME and more. But thats a very, VERY distant goal. For now, im focusing on getting a statically linked C binary running in userspace.
Current State
Iāve already managed to get some basic logging via serial and a basic framebuffer going, aswell as x86_64 GDT, IDT, TSS and a physical aswell as a very slim virtual memory manager.
Whats next?
Next, Iāll be āfinishingā up the VMM a little to be able to start work on the heap allocator, which will enable use of datatypes like Vec, Box and more.
nerd section
For anyone interested in the more technical stuff:
The build toolchain works through python scripts, which use docker to build and then QEMU to run the kernel.
Iām mainly targeting x86_64, but aarch64 support is also my plan (but Iāll be focusing on x86_64 during this challenge).