| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
| |
|
| |
|
|
|
|
| |
Starting to gain confidence.
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
Fix a couple of subtle bugs.
- the VM was conditionally reading from the instruction stream, so that
other bugs got masked by decoding errors.
- push-n-bytes was clobbering eax.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
| |
More copypasta. I'd be able to remove this duplication if we had first-class
functions, but they involve an accessibility cost.
|
| |
|
| |
|
|
|
|
| |
Now that we have a fake screen we can start testing it.
|
|
|
|
|
| |
We still need a few primitives, but we can implement these as needed. I'm
ready to call the fake screen done.
|
|
|
|
|
|
| |
No support for combining characters. Graphemes are currently just utf-8
encodings of a single Unicode code-point. No support for code-points that
require more than 32 bits in utf-8.
|
|
|
|
| |
Also more error-detection for this case all across the toolchain.
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
1000+ LoC spent; just 300+ excluding tests.
Still one known gap; we don't check the entirety of an array's element
type if it's a compound. So far we just check if say both sides start with
'addr'. Obviously that's not good enough.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There's a question of how we should match array types with a capacity on
ones without. For now we're going to do the simplest possible thing and
just make type-match? more robust. It'll always return false if the types
don't match exactly. For ignoring capacity we'll rely on the checks of
the `address` operation (which don't exist yet). This means we should do
this to pass an address to an array to a function f with signature `f (addr
array int)`:
var a: (array int 3)
var b/eax: (addr array int) <- address a
f b
rather than this:
var a: (array int 3)
var b/eax: (addr array int 3) <- address a
f b
Similar reasoning applies to stream types. Arrays and streams are currently
the only types that can have an optional capacity.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For example:
fn main -> r/ebx: int {
var x/eax: grapheme <- copy 0x9286e2 # code point 0x2192 in utf-8
print-grapheme-to-real-screen x
print-string-to-real-screen "\n"
}
Graphemes must fit in 4 bytes (21 bits for code points). Unclear what we
should do for longer clusters since graphemes are a fixed-size type at
the moment.
|
|
|
|
|
| |
This is stupid; all this while I've been writing escape sequences to the
screen they've been going out on stderr.
|
|
|
|
|
|
|
|
|
|
| |
Both have the same size: 4 bytes.
So far I've just renamed print-byte to print-grapheme, but it still behaves
the same.
I'm going to support printing code-points next, but grapheme 'clusters'
spanning multiple code-points won't be supported for some time.
|
| |
|
| |
|
|
|
|
|
| |
We now have all existing apps and prototypes going through the dependency-injected
wrapper, even though it doesn't actually implement the fake screen yet.
|
|
|
|
| |
There was a bug in defining types containing other user-defined types.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a hacky special case. The alternative would be more general support
for generics.
One observation: we might be able to type-check some primitives using `sig`s.
Only if they don't return anything, since primitives usually need to support
arbitrary registers. I'm not doing that yet, though. It eliminates the
possibility of writing tests for them in mu.subx, which can't see 400.mu.
But it's an alternative:
sig allocate out: (addr handle _)
sig populate out: (addr handle array _), n: int
sig populate-stream out: (addr handle stream _), n: int
sig read-from-stream s: (addr stream _T), out: (addr _T)
sig write-to-stream s: (addr stream _T), in: (addr _T)
We could write the tests in Mu. But then we're testing behavior rather
than the code generated. There are trade-offs. By performing type-checking
in mu.subx I retain the option to write both kinds of tests.
|
| |
|
|
|
|
|
|
|
|
|
| |
Slices contain `addr`s so the same rules apply to them. They can't be stored
in structs and so on. But they may be an efficient temporary while parsing.
Streams are currently a second generic type after arrays, and gradually
strengthening the case to just bite the bullet and support first-class
generics in Mu.
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
We need to remember to clear local variables. And there's a good question
here of how Mu supports variables of type stream or table. Or other user-defined
types that inline arrays.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Function signatures can now take type parameters starting with '_'.
Type parameters in a signature match any concrete type in the call. But
they have to be consistent within a single call.
Things I considered but punted on for now:
- having '_' match anything without needing to be consistent. Wildcards
actually seem harder to understand.
- disallowing top-level '_' types. I'll wait until a concrete use case
for disallowing.
We still don't support *defining* types with type parameters, so for now
this is only useful for calling functions on arrays or streams or handles.
|
|
|
|
|
| |
I think I've got all the stack management down. Time now for the business
logic. There's one failing test.
|