Tom Marks Talks Code LIVE
Tom Marks Talks Code LIVE
  • 46
  • 26 361
Building a Compiler - Struct Field Assignment | Live Rust Programming
Today we get simple struct field assignment working, eg `foo.x := 5`. This is a good start, and we setup a good foundation for working with struct field expressions on the right hand side of the equals sign.
Also we can now define local variables that are structs such that they are allocated on the stack, but there is still no value initialization!
Stream date: 2024-07-16
Support the stream: ko-fi.com/tommarkstalkscode
Source: github.com/phy1um/rust-simple-vm
Streamed live @ twitch.tv/TomMarksTalksCode
Follow me at coding.tommarks.xyz
Email: tom@tommarks.xyz
มุมมอง: 51

วีดีโอ

Building a Compiler - Adding Structs | Live Rust Programming
มุมมอง 6102 ชั่วโมงที่ผ่านมา
The stream I have been dreading, today we start work on structs. It's exciting, but SO complicated. To start off, we need to parse struct definitions, and custom user types in general. Then we start getting stuck into assignment to a struct field. Stream date: 2024-07-15 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed live @ twitch.tv/TomMarksTa...
Building a Compiler - Playing with a Virtual Screen | Live Rust Programming
มุมมอง 7044 ชั่วโมงที่ผ่านมา
It's time for round 2 of drawing to a virtual screen. This is going to expose any rough edges, and it looks like the stack is misbehaving. Luckily with the power of pen and paper we can step through the stack and I work out a solution that lets me populate a screen with absolute garbage! Also I added a hardware multiply instruction finally :D Stream date: 2024-07-14 Support the stream: ko-fi.co...
Building a Compiler - Type Inference | Live Rust Programming
มุมมอง 2699 ชั่วโมงที่ผ่านมา
It's time to make variable declaration awesome by getting rid of redundant type annotations. This went surprisingly well! I then move on and do some fun stuff with number parsing and clean up some strange quirks that had been bugging me :D Stream date: 2024-07-13 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed live @ twitch.tv/TomMarksTalksCode ...
Building a Compiler - Experimental Error Handling and Cleanup | Live Rust Programming
มุมมอง 23012 ชั่วโมงที่ผ่านมา
In this stream I try to make error reporting better, then realize that it's a big fish to try to catch! I do some great brainstorming but hit a lot of dead ends. I do end up improving my function body parser quite a lot! Then on to a LOT of misc cleanup :D Stream date: 2024-07-11 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed live @ twitch.tv/T...
Building a Compiler - Expression Brackets and Error Reporting | Live Rust Programming
มุมมอง 23514 ชั่วโมงที่ผ่านมา
It's time to make expressions more expressive by supporting grouping things with brackets. It almost seems too easy, and it might just work off of the bat. With nested expressions piling up, it's probably time to do some better error reporting too :D Stream date: 2024-07-10 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed live @ twitch.tv/TomMark...
Building a Compiler - Fixing Stack Pointers | Live Rust Programming
มุมมอง 26416 ชั่วโมงที่ผ่านมา
Pointers to the stack are broken, so let's fix them. Then it's time to write some sample programs for my virtual screen, and resolve any problems that come up along the way! Stream date: 2024-07-08 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed live @ twitch.tv/TomMarksTalksCode Follow me at coding.tommarks.xyz Email: tom@tommarks.xyz
Building a Compiler - Dereferencing Addresses With Pointers | Live Rust Programming
มุมมอง 25421 ชั่วโมงที่ผ่านมา
Now it's time to dereference those addresses! I discover that pointers behave a bit differently on the left hand side and right hand side of an assignment, and finally write some data to memory from my language :D Book mentioned in the stream: sicp.sourceacademy.org/sicpjs.pdf Stream date: 2024-07-07 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Stream...
Building a Compiler - Fixing Globals and Stating Pointers | Live Rust Programming
มุมมอง 265วันที่ผ่านมา
In this stream we fix some annoying issues with globals, then finally start implementing pointers, so that people can officially ask "what is a pointer?" when they start to learn this language. This stream is the address-of operator only, dereferences are coming next :D Stream date: 2024-07-05 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed live...
Building a Compiler - Global Scope | Live Rust Programming
มุมมอง 403วันที่ผ่านมา
Adding globally scoped variables to my so that we can write escape from rust and write thoroughly borrow checker unsafe code :D Stream date: 2024-07-04 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed live @ twitch.tv/TomMarksTalksCode Follow me at coding.tommarks.xyz Email: tom@tommarks.xyz
Adding Inline Assembly to my Compiler | Live Rust Programming
มุมมอง 32214 วันที่ผ่านมา
Adding special syntax to my programming language so that I can make fake functions that are really implemented in raw assembly. This will help bridge gaps in my language while I'm developing :D Stream date: 2024-07-02 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed live @ twitch.tv/TomMarksTalksCode Follow me at coding.tommarks.xyz Email: tom@to...
Building a Compiler in Rust | Block Scoped Locals | Live Rust Programming
มุมมอง 26314 วันที่ผ่านมา
I made a pretty dumb mistake at the end of the last stream by forgetting to zero out a variable at the start of each loop. Let's make it harder for this kind of error to happen by adding block-scoped variables. This turns into a bit of a borrow checking nightmare, but I have enough understanding of Rust to overcome it now :D Stream date: 2024-07-01 Support the stream: ko-fi.com/tommarkstalkscod...
Building a Compiler - While Loops | Live Rust Programming
มุมมอง 1K14 วันที่ผ่านมา
Today we tackle while loops! This will be important for writing real, useful code that does things. I also get distracted and start fiddling with the Rust workspace. This stream ends with loops working but me being dumb about the tests :D Stream date: 2024-06-28 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed live @ twitch.tv/TomMarksTalksCode F...
Virtual Hardware for my VM | Live Rust Programming
มุมมอง 53014 วันที่ผ่านมา
Using my memory mapper API to build virtual hardware. In this stream I get a byte stream working, which lets me simulate a dumb serial terminal and finally run a hello world program! I am scared to calculate how long it took me to get to "hello world" with this project :D Stream date: 2024-06-27 Support the stream: ko-fi.com/tommarkstalkscode Source: github.com/phy1um/rust-simple-vm Streamed li...
Proxying Mutability in Javascript | Live Rust Programming
มุมมอง 18021 วันที่ผ่านมา
Passing a mutable struct from WASM into JS is hard when you try to adhere to Rust's memory model. Let's work around that completely by using a proxy object! This object will accumulate the actions we want to commit to the data on the Rust/WASM side, and we'll think of a clever way to pass data from reads back to JS... hopefully :D Stream date: 2024-06-26 Support the stream: ko-fi.com/tommarksta...
Calling Javascript From My 16bit VM | Live Rust Programming
มุมมอง 67521 วันที่ผ่านมา
Calling Javascript From My 16bit VM | Live Rust Programming
Building a Compiler - Finally Fixing Recursion | Live Rust Programming
มุมมอง 51521 วันที่ผ่านมา
Building a Compiler - Finally Fixing Recursion | Live Rust Programming
Building a Compiler - Fixing Jumps, Recursion Broken | Live Rust Programming
มุมมอง 53921 วันที่ผ่านมา
Building a Compiler - Fixing Jumps, Recursion Broken | Live Rust Programming
Better Error Messages - Building a Compiler | Live Rust Programming
มุมมอง 339หลายเดือนก่อน
Better Error Messages - Building a Compiler | Live Rust Programming
Adding Function Arguments to my Compiler | Live Rust Programming
มุมมอง 203หลายเดือนก่อน
Adding Function Arguments to my Compiler | Live Rust Programming
Working on my Compiler | Live Rust Programming
มุมมอง 593หลายเดือนก่อน
Working on my Compiler | Live Rust Programming
Rust+Bevy GameDev LIVE | LDTK Integration
มุมมอง 95หลายเดือนก่อน
Rust Bevy GameDev LIVE | LDTK Integration
Rust+Bevy GameDev LIVE | Smarter Enemy Spawner
มุมมอง 76หลายเดือนก่อน
Rust Bevy GameDev LIVE | Smarter Enemy Spawner
Rust+Bevy GameDev LIVE | Gamepad Input
มุมมอง 32หลายเดือนก่อน
Rust Bevy GameDev LIVE | Gamepad Input
Rust+Bevy GameDev LIVE | Player Movement and New Input System
มุมมอง 272หลายเดือนก่อน
Rust Bevy GameDev LIVE | Player Movement and New Input System
PS2 GameDev LIVE! Running My First VU1 Program
มุมมอง 138หลายเดือนก่อน
PS2 GameDev LIVE! Running My First VU1 Program
Rust+Bevy GameDev LIVE | New Menu UI and Polish
มุมมอง 592 หลายเดือนก่อน
Rust Bevy GameDev LIVE | New Menu UI and Polish
Rust+Bevy GameDev LIVE | Building a Texture Atlas at Runtime
มุมมอง 1902 หลายเดือนก่อน
Rust Bevy GameDev LIVE | Building a Texture Atlas at Runtime
PS2 GameDev LIVE! Transferring Programs to a Vector Unit
มุมมอง 3252 หลายเดือนก่อน
PS2 GameDev LIVE! Transferring Programs to a Vector Unit
PS2 GameDev LIVE! Finally Getting VIFCodes Right
มุมมอง 592 หลายเดือนก่อน
PS2 GameDev LIVE! Finally Getting VIFCodes Right

ความคิดเห็น

  • @div0826
    @div0826 วันที่ผ่านมา

    ❤❤❤❤

  • @miketag4499
    @miketag4499 วันที่ผ่านมา

    Awesome video, thanks for sharing

  • @nosuchthing8
    @nosuchthing8 วันที่ผ่านมา

    Amazing!!!

  • @valshaped
    @valshaped วันที่ผ่านมา

    Highly recommend studying the pattern syntax; the answer to, "Can I get the value of this subfield in a match arm?" is yes, unless you're trying to match on the contents of a Box, in which case the answer is unfortunately no (for now). Also, naturally relocatable code that fully utilizes offsets is wonderful when you don't have a proper linker :P

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 22 ชั่วโมงที่ผ่านมา

      Maybe I need to bite the bullet and invent a binary format instead of relying on everything being a blob :D

  • @ingmarfalk3306
    @ingmarfalk3306 2 วันที่ผ่านมา

    Something I like doing is to not return an Error result, but rather always return a valid AST node. This could mean returning an error node. This allows me to parse the entire input and check for any errors further down. If I encounter an error, I use a diagnostic emitter to send the error either to a channel (prefer that) or if you wanna go simple just append it to a list. Works like a charm tbh

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 2 วันที่ผ่านมา

      My current plan is to have some "continuable" errors return a valid state, so rather than just bubbling up with a `?` I can have some helper that matches on the error and possibly continues. Ultimately I think my state needs to maybe accumulate these errors, plus some other metadata, to make error reporting sensible.

    • @ingmarfalk3306
      @ingmarfalk3306 2 วันที่ผ่านมา

      Or well, maybe not an error node but a default node (maybe a default statement or sth) and tag it with some information either on the node directly or in a side table.

  • @DMWatchesYoutube
    @DMWatchesYoutube 3 วันที่ผ่านมา

    DEADBEEF < FEEDADAD

    • @DMWatchesYoutube
      @DMWatchesYoutube 3 วันที่ผ่านมา

      It's funny because it's true

  • @div0826
    @div0826 4 วันที่ผ่านมา

    ❤❤❤❤❤❤❤

  • @theantonlulz
    @theantonlulz 4 วันที่ผ่านมา

    Newbie question from someone relatively new to the industry: is it worth it learning vim (with all it entails) if my place of work does not mandate everyone to use the same dev setup? (other than the fact that we all get laptops with Windows installed)

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 3 วันที่ผ่านมา

      For work you should use what you are comfortable with. Learning vim is a commitment, and it has been extremely valuable to me, but in every paid job I have used JetBrains IDEs because I find it a bit easier with really big codebases. I want to try using vim for my next job, but I'll have to setup LSP etc better. I think it's worth forcing yourself to learn some vim basics even if it doesn't become your main editor though. It's an awesome editor with a rich history!

  • @div0826
    @div0826 5 วันที่ผ่านมา

    Great video.

  • @valshaped
    @valshaped 5 วันที่ผ่านมา

    Predictive parsers are very nice to work with. My current parser is entirely predictive, and never backtracks. It has its downsides (for example, I had to change struct-initializer expressions so they wouldn't conflict with the condition of an if expression) but if you can make your grammar predictable, your parser will FLY! And, yeah, re-synchronizing the parser after an error is difficult. I think, usually, people advance until the next recognizable bit of syntax (the ending brace, bracket, parenthesis, semicolon, any kind of terminator) and skip the errored code.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 4 วันที่ผ่านมา

      I have a vague plan for how to incorporate a "continuable" error into my errors, and I probably shouldn't leave that too long because the errors are already so hard to read 😅 I've only parsed lisps/s-expressions before so the complexity here is very new to me

    • @valshaped
      @valshaped 4 วันที่ผ่านมา

      @@TomMarksTalksCodeLIVE I feel you. Conventional algebraic PLs have so much more syntax than a Lisp, and proper error recovery only makes it more difficult. You're doing good work.

  • @DMWatchesYoutube
    @DMWatchesYoutube 5 วันที่ผ่านมา

    Just got a simple program running in a VM im writing in zig. Gotta work on a memory iterator to make program execution smoother. I've decided not to separate registers from general memory, but it's working well so far

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 4 วันที่ผ่านมา

      I would love to do some Zig streams one day!

    • @DMWatchesYoutube
      @DMWatchesYoutube 4 วันที่ผ่านมา

      It's fun to mess around with, I haven't done anything huge in it yet, but I'm heading that way lol. I love meta programming and have tried a lot of languages and I honestly like zig the best for that

  • @hudsonfinn7001
    @hudsonfinn7001 5 วันที่ผ่านมา

    First of all, great video. I've started on my own implementation of an LC3-VM in Rust as well. Your repo link in the description is broken. It appears to be truncated.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 4 วันที่ผ่านมา

      Fixed the link, that's so random haha. Thanks <3

  • @sethrenshaw8792
    @sethrenshaw8792 5 วันที่ผ่านมา

    😅Trying to help explain things from TH-cam comments is quite the rollercoaster, but getting up at 7am my time to catch your streams is, unfortunately, a little too much, I think.

  • @sethrenshaw8792
    @sethrenshaw8792 5 วันที่ผ่านมา

    @1:08:15 I think you can simplify that whole mess by using: options.fold(options[0], |a, b| if a.confidence > b.confidence { a } else { b }) The thing you care about is which ConfidenceError has the greater _Confidence_. Which means you care about how the Confidence values compare _not_ how or whether the ConfidenceError objects themselves can compare. (edit) Which you seem to have figured out a little bit later.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 5 วันที่ผ่านมา

      I do stream at random times sometimes, I'm going to try to commit to a better schedule in my Discord with some earlier and later streams in my strange Australian timezone so that people can catch me live. I really appreciate the comments! edit: oops this supposed to be a response to a later comment. It still stands though :D

  • @sethrenshaw8792
    @sethrenshaw8792 5 วันที่ผ่านมา

    @42:59 No, no. It wants you to use the `matches` macro! The warning mentions just below the message: "try: `matches!(self, Self::Pointer(_))`. The matches macro is useful when you _only_ care about whether something is one of the specified enum variants, _not_ what's inside the variant.

  • @sethrenshaw8792
    @sethrenshaw8792 5 วันที่ผ่านมา

    @38:18 If you want to go the _full_ functional approach, you could use something like this to replace the whole for-loop (assuming I got all the syntax right): self.items .map(|item| item.run(s.clone())) // run each item lazily .find(Result::is_ok) // find the first successful item .map(|result| result.map(|(s, t)| (s, Some(t)))) // if an item was found, transform the result to the correct form .unwrap_or(Ok((s, None))) // if no item was found, use the fallback

  • @sethrenshaw8792
    @sethrenshaw8792 5 วันที่ผ่านมา

    @16:45 You mention previously you wouldn't have been able to parse "*x + 5", which presumably you can after moving expression_deref to expression_lhs. I just wanted to point out, you should probably add a test for that. ;) Also, you may want to add a test for something like "5 * *x", just to make sure your expression parsing doesn't get confused when seeing something weird like that.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 5 วันที่ผ่านมา

      My test suite has more holes than a sieve, I really need to commit some love and care to it :D Now that I've decided to commit to a multiply instruction I definitely need better testing around the 2 meanings of `*`

  • @valshaped
    @valshaped 6 วันที่ผ่านมา

    1:15:00 Yup! PhantomData is the only type allowed by the compiler to have unused generics. It has special type inference shenanigans going on, iirc. It's necessary when you have a type that *represents* having ownership of some T, but doesn't actually have an instance of T. You can actually be even more explicit about the relationship between your PhantomData-containing type and T: struct HasPhantom<T> { /// I don't have a T, but I consume a T _fn_arg: PhantomData<fn(T)>, /// I don't have a T, but I construct a T _fn_ret: PhantomData<fn() -> T>, /// I contain something that represents a mutable reference to a T, but doesn't borrow-check as one (i.e. a raw pointer *mut T, or ptr::NonNull<T>) _mut_ref: PhantomData<&mut T>, // etc. } The Rust Reference and Rustnomicon have pretty good info on what, when, and where a PhantomData should be. The latter is especially useful if you're writing unsafe code. Usually it has to do with "Subtyping and Variance". In your case, you're using it as shorthand for omitting generics on every member function of that type, which I'd argue is a totally valid use.

  • @JoQeZzZ
    @JoQeZzZ 7 วันที่ผ่านมา

    Idiomatic read2 would be more like: fn read2(&self, addr: u16) -> Option<u16>{ let x0 = self.read(addr)?; let x1 = self.read(addr+1)?; (x0 as u16) | (x1 as u16 << 8) } The ? operator returns the None or Err type from an option or result and otherwise unwraps the Some or Ok type and continues with the expression. It's syntactic sugar for if let read(addr)=Some(x0){ <do smething> }else{ return None } or x0 = match self.read(addr){ None => return None Some(a) => a } Which is what you want to do anyway. This coincidentally is also why you don't want to return a bool for your write function. For one it's less clear what you mean, an Option<()> or a Result<(),()> shows intention better, but secondly it also gives you the ability to just ? any errors up the chain. Also, I believe an Option<_> is always preferred over a Result<_, ()>, because you're not adding anything with the empty Err type. You're saying: this failed in the only way that is possible, which is precisely what Option<_> does. On the contrary, Option<()> says: this function doesn't return anything when things go well, but it can fail in exactly one way. This is what write should return IMO. Also also, if you later need do need two error types, say for your copy function (ReadError, WriteError), you can do the following: fn copy(&mut self, from: u16, to: u16) -> Result<(),MemErr>{ let x = self.read(from).ok_or(ReadError)?; self.write(to, x).ok_or(WriteError) } Here you cast the Option<T> to a Result<T, Err>, which you then unwrap/return with ?. This type of error handling is IMO a major advantage of rust. For the final write you don't even need to add a ?, because you'll be returning nothing if write returns nothing and the error if it returns an error, so why not just return the result of the ok_or(..) directly :)

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 6 วันที่ผ่านมา

      Thank you, I've learned quite a bit about functions like `ok_or` and better use of Option/Result/? in my functions as this series goes on, largely thanks to helpful comments like this. The `read2` you suggest is actually exactly what it looks like now: github.com/phy1um/rust-simple-vm/blob/main/vm/src/memory.rs#L40 It's good to know I'm on the right track :D

    • @JoQeZzZ
      @JoQeZzZ 6 วันที่ผ่านมา

      @@TomMarksTalksCodeLIVE awesome, looking really cool! I especially like the macro implementation for the opcode generation. Will definitely look into that video later

  • @klineaugust
    @klineaugust 7 วันที่ผ่านมา

    youtube won't let me post the link, but the mdn web docs have a short guide on crisp upscaling for pixel art in canvases, you basically set the canvas element's width and height to match the dimensions of the art (in this case, the virtual screen), and then in CSS you set the width/height to some multiple of the element's width/height and set image-rendering: pixelated

    • @klineaugust
      @klineaugust 7 วันที่ผ่านมา

      i'm only at the start of the video so apologies if i'm explaining something that was already solved!

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 6 วันที่ผ่านมา

      I thought I would be able to copy from one canvas to another with pixel perfect scaling, but I think I do need to just scale the canvas that is linked into the VM memory. Thanks!

    • @klineaugust
      @klineaugust 6 วันที่ผ่านมา

      @@TomMarksTalksCodeLIVE ofc! glad i could help!

  • @stigmag
    @stigmag 7 วันที่ผ่านมา

    what is the color theme you are using?

  • @DMWatchesYoutube
    @DMWatchesYoutube 7 วันที่ผ่านมา

    A pronunciation proposal for 0xff "feety f" 0xF2EA = F thousand Two hundred and Eety A

  • @DMWatchesYoutube
    @DMWatchesYoutube 7 วันที่ผ่านมา

    Someone is watching this right now with me 👋 good stuff huh

  • @ssublexff3465
    @ssublexff3465 8 วันที่ผ่านมา

    Hello there, you are a legend first of all but the link of your git repo is not correct if were to change it for others it would be great, here it is phy1um/rust-simple-vm

  • @diogomartins4105
    @diogomartins4105 9 วันที่ผ่านมา

    hi! what's that environment you use? great video!

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 8 วันที่ผ่านมา

      Archlinux, alacritty terminal, dwm for window management. Mostly vanilla neovim for editing.

  • @valshaped
    @valshaped 9 วันที่ผ่านมา

    The `Extend` trait is a generalization of vec.append(other) that takes any IntoIterator as the other. You can *totally* pass a statically sized array! out.extend( [ Instruction::Pop(SP, BP), Instruction::Pop(SP, PC) ] ); Also, the Rust `core` library isn't allowed to allocate on the heap. Allocation happens in the `alloc` library, which has `core` as a dependency. `std` exports both `core` and `alloc`.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 9 วันที่ผ่านมา

      I still have a pending TODO to fix up my Vec<T> abuse in this code :D

    • @valshaped
      @valshaped 9 วันที่ผ่านมา

      @@TomMarksTalksCodeLIVE That's what prototypes are for! You can't make an omelette without thrashing a few heaps.

  • @DMWatchesYoutube
    @DMWatchesYoutube 9 วันที่ผ่านมา

    If rust becomes very popular, there will be people who say, "i just like to use C. it's better to prototype with".

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 9 วันที่ผ่านมา

      That is probably true! You can hack together some pretty good stuff in C pretty fast if you know what you're doing. Rust will always have more overhead, but I'm starting to feel that having the compiler assert correctness is saving me a lot of energy on this project even if it has taken more time to get features in.

  • @valshaped
    @valshaped 10 วันที่ผ่านมา

    RefCell *only* does runtime borrow checking; Rc *only* does reference-counting. Therefore, Rc<RefCell<T>> does reference-counting of a runtime borrow-checked T Regarding impl/dyn Trait: `fn example(t: impl Trait) { ... }` is equivalent to `fn example<T: Trait>(t: T) { ... }` `fn example() -> impl Trait { ... }` creates an opaque return type that the caller is not allowed to introspect (which is great if you can't name the return type) `fn example(t: Box<dyn Trait>) { ... }` and `fn example() -> Box<dyn Trait> { ... }` use a "trait object," which looks up trait methods in a vtable like an object in C++. You can only call trait methods specified in `Trait`'s contract

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 9 วันที่ผ่านมา

      Even with all of the experience I've gained since this stream, this very precise explanation has taught me some new stuff. Thanks for your continued comments, I'm finding them really valuable <3

    • @valshaped
      @valshaped 9 วันที่ผ่านมา

      @@TomMarksTalksCodeLIVE Aw, thanks! Hopefully I'll catch up with these VODs and join your livestream chat sometime <3

  • @DMWatchesYoutube
    @DMWatchesYoutube 10 วันที่ผ่านมา

    Got recommended your first video it seems, lots of stuff to binge nice

  • @varshneydevansh
    @varshneydevansh 10 วันที่ผ่านมา

    I also used to had long mane Subbed your channel

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 9 วันที่ผ่านมา

      Thank you :D Do you mean my hair?

    • @varshneydevansh
      @varshneydevansh 9 วันที่ผ่านมา

      @@TomMarksTalksCodeLIVE yes. I miss mine so much. Probably I will go through your playlist. I had so many plans, but my health didn't let me do stuff. Currently doing GSoC and Ben Eaters 8-bit computer. But, I find you a person who is doing TH-cam out of his interest

  • @bort2793
    @bort2793 10 วันที่ผ่านมา

    What programming language should I start with as a complete beginner who barely remembers how to write hello world in python

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 10 วันที่ผ่านมา

      It depends on what you want to do. Python is a good choice, there is lots of good documentation. If you want to do any frontend web stuff do Javascript. Golang will require more upfront investment but it is also a really solid beginner language imo.

  • @valshaped
    @valshaped 11 วันที่ผ่านมา

    34:24 Imm A 4080 (0xffc) :P Gotta love when your expectations are tested for validity 1:44:00 YESSSSSS become one with the RISC. I love me some {pc, sp, sr, cg} action

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 10 วันที่ผ่านมา

      It's hard when my bad expectations are tested against the reality that I also created 🙃 RISC is always fun, the computer arch course I did at uni was all about RISCV and it changed the way I think. Before that I thought x86 asm looked cool, now I can't stand it :D

  • @valshaped
    @valshaped 11 วันที่ผ่านมา

    Oh, yeah. repr(u8) disables niche optimization. That could have very minor performance impacts, and could increase the size of other enums by 1-8 bytes. That's pretty far into the weeds, though.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 11 วันที่ผ่านมา

      Yeah that turned out to be a dead end anyway, hard to remember exactly what I was doing back here but pretty sure I end up using proc macro attributes to make that line of thinking redundant.

  • @valshaped
    @valshaped 11 วันที่ผ่านมา

    Collect asks the inferred return type to construct itself from an Iterator via the FromIterator trait :P The standard library, and external libraries, are full of gorgeous little gems like it! ``` Iterator::collect<Collection>(self) -> Collection where Collection: FromIterator<Iterator::Item> ``` Generic return types are one of the reasons I love Rust as much as I do: it requires good type inference. Another amazing trait is `From`, and its magic type-inference cousin `Into` I've been trying to write my own language's type system, and I can't seem to wrap my head around anything more complicated than Algorithm W.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 11 วันที่ผ่านมา

      I really love from and into, I keep seeing cool uses for them. I feel like the next codebase I start will be way more intentional with that stuff :D

  • @user-fj9hf4bu9f
    @user-fj9hf4bu9f 12 วันที่ผ่านมา

    Your accent sounds like vegan-newtown, is that correct?

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 11 วันที่ผ่านมา

      I'm from Adelaide. I was talking through some git stuff the other day and my friend made fun of me for how posh I said "branch"

  • @valshaped
    @valshaped 13 วันที่ผ่านมา

    OPERATOR PRECEDENNNNCCCEEEEEE For future viewers: this is why you run `cargo clippy` Also, `u8 as i8 as u8 as i8` doesn't throw away any information or do any conversion. It's a pure bit reinterpret

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 13 วันที่ผ่านมา

      I've been lazy with clippy haha. I didn't realize `as` casts worked like that, thank you so much for the comments

    • @valshaped
      @valshaped 13 วันที่ผ่านมา

      @@TomMarksTalksCodeLIVE Of course! `as` casting on primitives works similarly to casting numerics in C; Depending on the operands, `as`: - Reinterprets (i.e. 0xff_u8 as i8 == -1_i8) - Zero extends (unsigned operands, i.e. 0xff_u8 as u16 == 0x00ff_u16) - Sign extends (signed operands, i.e. -1_i8 as i16 == -1_i16) - Truncates (0xff00_u16 as u8 == 0x00_u8, -256_i16 as i8 == 0_i8) - Converts to float (100_u16 as f32 == 100.0_f32) - Saturates from float (512.0_f32 as i8 == 127_i8) doc.rust-lang.org/rust-by-example/types/cast.html

  • @valshaped
    @valshaped 13 วันที่ผ่านมา

    50:55 You can put your local function inside the function from_str, and it'll be private to within from_str fn outer () -> i32 { fn inner () -> i32 { 100 } inner() // returns 100 }

  • @valshaped
    @valshaped 13 วันที่ผ่านมา

    You can do almost anything with declarative macros :P (note: this is incomplete, refer to the rust reference for more info) ```rust macro_rules! instructions ( $(#[$attribute:meta])* $vis:vis enum $Name:ident { $( $variant:ident $( ($($t:tt)*) )? = $opcode:literal ),* $(,)? } ) { $(#[$attribute])* $vis enum OpCode { $( $variant = $opcode ),* } impl TryFrom<u16> for OpCode { type Error = String; fn try_from(value: u16) -> Result<Self, Self::Error> { match value & 0xff { $( $opcode => Ok(Opcode::$variant) ),* other => Err(format!("Unrecognized opcode: 0x{other:02x}")), } } } $(#[$attribute])* $vis enum $Name { $( $variant $( ($($t)*) )?),* } ... } ``` Also, the second paragraph of the quote macro docs tells you how to do the thing lmao

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 13 วันที่ผ่านมา

      I struggle a bit with the quote macro docs, apologies in advance for future streams :D This declarative macro is both hideous and beautiful, I am in awe

    • @valshaped
      @valshaped 13 วันที่ผ่านมา

      @@TomMarksTalksCodeLIVE I'll be honest, I've been avoiding proc-macros because decl-macros are just barely good enough to commit metaprogramming crimes with :P What you came up with is not only far more elegant, it reflects the semantics of your end result way better than a heinously large decl macro with a billion levels of $($repetition),*

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 12 วันที่ผ่านมา

      There is definitely room for improvement in my proc macros, but I will take the encouragement :D Cheers

  • @valshaped
    @valshaped 13 วันที่ผ่านมา

    Rust requires explicit casts for safety and correctness; coercion of integer widths will lose data (even if that lost data is always 0x00). That said, casting unsigned integers will always truncate or extend in-place.

  • @valshaped
    @valshaped 13 วันที่ผ่านมา

    If you use ddg, you can search "!rust Option" and it'll take you to the rust docs for Option :P

  • @valshaped
    @valshaped 13 วันที่ผ่านมา

    Rust enums are implemented via tagged unions, and the tag is known as the "discriminant". Enum variants are structs + discriminant A "niche" is any bit pattern that is guaranteed to be invalid for a type. An enum whose variants all contain niches can pack into the largest size and largest alignment of its variants, by assigning invalid bit patterns as enum discriminants. References, NonZero<T>, etc. have a single niche, so Option<&T> and Result<&T, ()>/Result<(), &T> are the same size as &T (Option<&T>::None == NULL). *bool* has 254 niches, so you can have one variant which contains a bool and 254 variants which contain nothing, and it should still pack into a byte. In general, enums have the memory overhead of their largest variant + (the discriminant if niche optimization doesn't apply.) The time overhead of enums is the same as a list of constants, and matching on that kind of enum is equivalent to `switch (enum.discriminant) {}`. Moving an enum is proportional to its length. Also you were trying very hard not to put all your definitions in one place match op & 0xff { 0 => Op::Nop, 1 => Op::Push((op >> 8) as usize), _ => ... } Note: the above code will be compiled as a jump table, but the code you wrote may be compiled to an if-else chain.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 13 วันที่ผ่านมา

      Thank you for this insight, I've learned quite a lot since this stream, but these enum details are very useful!

    • @valshaped
      @valshaped 13 วันที่ผ่านมา

      @@TomMarksTalksCodeLIVE You're welcome! Thanks for putting on such awesome live streams. Wish I could've caught you live 4 months ago; I've got a lot of VODs to catch up on :P

    • @JoQeZzZ
      @JoQeZzZ 7 วันที่ผ่านมา

      @valshaped A bool has 2 possible options, and since an enum is a sum type, doesn't that mean a single enum can have 128 variants that contain a bool for it to fit into a byte (128x2 = 256)? What you're describing is an enum with a single bool variant and 254 empty variants. (1x2 + 254x1) In other words, looking it as a bit field, 7 bits tell you which variant is selected and a single bit tells you the value of the containing bool. There is no way to sneak more data in there.

    • @valshaped
      @valshaped 7 วันที่ผ่านมา

      @@JoQeZzZYou're right that it'd use a bitfield if you had more than one bool variant, that's a mistake on my part. I fixed it in my comment above :D

  • @fireloks6362
    @fireloks6362 13 วันที่ผ่านมา

    My Rust is a little rusty! 😂

  • @dexedrine404
    @dexedrine404 13 วันที่ผ่านมา

    can I ask what font you use? It looks a lot cleaner than mine.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 13 วันที่ผ่านมา

      DejaVu Sans Mono. I chose it for streaming because it's so clean and seems to encode really well!

  • @solargamz4972
    @solargamz4972 14 วันที่ผ่านมา

    Great series so far! I experimenting with the vm and I'm pretty sure I found an error where jumping to PC 0 using "Imm PC 0" will cause an Invalid Instruction to be emitted instead of the first instruction of the instruction set. Not sure if it's current causing any issues but the init instructions may be hiding it by occupying the fist slots.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 13 วันที่ผ่านมา

      It's exciting to hear someone is experimenting with the VM :D I'm not totally sure what you mean though, "Imm PC 0" is definitely valid and this simple program loops forever as expected: AddImm B 1 Imm PC 0

    • @solargamz4972
      @solargamz4972 13 วันที่ผ่านมา

      ​@@TomMarksTalksCodeLIVE Oh strange, yeah that's definitely working... Well maybe its an issue with my instructions. I was trying to create a simple while loop: (currently just stores a variable forever but it fails on the first jump back) ; Cond (1 != 0 essentially) Imm C 1 Stack C SP Push Stack C SP Pop Test C Zero EitherNonZero AddIf PC PC 2 Imm PC 26 ; Body Imm C 7 Stack C SP Push Stack C SP Pop Add BP Zero B AddImm B 0 StoreWord B Zero C Imm PC 0 ; End Imm C 240 System C Zero 0 FYI: If you add a junk instruction to PC 0 and add 2 to all the jumps it runs as intended

  • @wesleylewis9140
    @wesleylewis9140 14 วันที่ผ่านมา

    Absolutely loving the coding sessions till now! Learning a lot from you, Keep it up! 💯

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 13 วันที่ผ่านมา

      Thank you so much, I'm happy that people are learning!

  • @klineaugust
    @klineaugust 16 วันที่ผ่านมา

    sweet video :) really impressive ur not using rust-analyzer! lsp makes writing rust sooo much easier

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 16 วันที่ผ่านมา

      Thank you! I think it keeps the streams clean and it lets me think everything through without interruption and red squiggly lines.

  • @jtw-r
    @jtw-r 17 วันที่ผ่านมา

    4:30 Cache invalidation and naming things are the two biggest hurdles in programming

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 16 วันที่ผ่านมา

      Apparently this was actually said by Phil Karlton. The 2 biggest problems are naming things, cache invalidation and off by one errors. I don't know why I wrongly attributed this so badly :D

  • @marsovac
    @marsovac 17 วันที่ผ่านมา

    "And I can't spell" - this is why you use a GUI for git... so that you dont have to type, add manually, and spend a lot of time checking diffs.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 16 วันที่ผ่านมา

      I still prefer to hack it out on the terminal rather than go into a different program and click around. I'm open to learning some TUI that integrated with nvim though.

  • @lucasa8710
    @lucasa8710 17 วันที่ผ่านมา

    I love this type of content

  • @kurzschlussjunkies
    @kurzschlussjunkies 18 วันที่ผ่านมา

    Reset b every time your a loop runs. Otherwise b loop only runs once.

    • @TomMarksTalksCodeLIVE
      @TomMarksTalksCodeLIVE 17 วันที่ผ่านมา

      I know, I feel so dumb :D I realized this in between streams