Commit Graph

10 Commits

Author SHA1 Message Date
c286937e0a Maybe fix lexer lexeme issue once and for all
This is an ongoing off-by-one bug that I have not expended enough
brainpower to try to fix. Sometimes lexer outputs were getting chopped
off by one character at the EOF. I have changed a <= to a < to detect if
we're at EOF and that appears to have fixed everything. Getting really
tired of this but hopefully that's all that's needed.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-10-15 14:04:15 -07:00
16ab9d718b Add augmented assignment operators for set statements
This allows us to do things like

    self.foo += 5

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-10-07 11:05:39 -07:00
365bee0554 Implement augmented assignment operators
Add support for +=, -=, *=, and /= operators. This is basically just
syntactic sugar, but it's still nice to have

    a += 1

compiles to the equivalent of

    a = a + 1

with all the same implications of scoping rules.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-10-07 10:23:15 -07:00
19dd90755d Fix EOF error in parser
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-10-04 11:07:42 -07:00
f0de5f7850 WIP: Add imports and modules
This is a big change because it touches a lot of stuff, but here is the
overview:

* Import syntax:
    ```
    import foo
    import bar from foo
    import bar from "foo.npp"
    import bar, baz from foo
    import * from foo
    import "foo.npp"
    ```
    * These are all valid imports. They should be pretty
      straightforward, maybe with exception of the last item. If you are
      importing a path directly, but not importing any members from it,
      it does not insert anything into the current namespace, and just
      executes the file. This is probably going to be unused but I want
      to include it for completeness. We can always remove it later
      before a hypothetical 1.0 release.
    * The "from" keyword is only ever used as a keyword here, and I am
      allowing it to be used as an identifier elsewhere. Don't export
      it, because that's weird and wrong and won't work.
* Modules:
    * Doing an `import foo` will look for "foo.npp" at compile-time,
      relative to the importer's directory, parse it, and compile it.
      The importer will then attempt to execute the module with the new
      `EnterModule` op. This instruction will execute the module kind of
      like a function, assigning the module's global namespace to an
      object that you can pass around.
    * `import bar from foo` and `import bar from "foo.npp"` et al syntax
      is not currently implemented in the compiler.
    * There is a new "Module" object that represents a potentially
      un-initialized module. This can't be referred to directly in code.
* VM:
    * The VM operates around Module objects now. If you want to "call" a
      new module, you should call `enter_module`. This is how the main
      chunk is invoked.
* TODOs:
    * `exit_module` function in the VM
    * Finish up module implementation in compiler
    * Built-in modules
    * Sub-modules - e.g. `import foo.bar` - how does naming work for
      this?
    * Module directories. In Python you have `foo/__init__.py` and in
      Rust you have `foo/mod.rs`.
    * Probably a "Namespace" object that explicitly denotes "this is an
      imported module that you're dealing with"
    * Tests, tests, tests

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-10-04 10:11:49 -07:00
dab474a037 Add lists
This introduces:

* new syntax for list literals, put comma-separated values between
  braces for your new list
* new syntax for indexing, do `foo[index]` to get the value in `foo` at
  `index`. Lists also allow negative indices too. Any type that wants to
  be indexed can include their own __index__ function as well.
* new VM instruction, BuildList. List literals were a lot easier to
  implement using this rather than creating a new list, creating a
  temporary stack value, and then duplicating + pushing to that
  temporary value over and over.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-09-30 16:33:58 -07:00
645105c2c5 Remove kebab-case from parser. It was not being used.
This is a simple one. It does not make sense for an infix language that
uses `-` as a first-class binary (and more importantly, unary) operator.
I liked the idea, but I don't think it was going to work. Plus, I wasn't
using it for builtin functions in the first place, so why keep it
around? Underscores are just fine for our purposes.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-09-26 10:47:53 -07:00
1dd058ae18 Add binary and hex number parsing
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-09-26 10:03:54 -07:00
11a5a1247e Fix mix-up in the parser
>= and > had gotten mixed up and were being parsed as each other. This
is fixed.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-09-24 17:16:47 -07:00
16f3dc960c Base initial commit
Still WIP, working on object system still, which in Rust, makes me want
to kill myself

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2024-09-20 16:04:30 -07:00