WIP passing args and returning values from a function call. Updates to documentation, update logo

This commit is contained in:
zongor 2025-10-24 23:04:05 -07:00
parent 790d7e8509
commit 3be8761930
23 changed files with 609 additions and 1921 deletions

View File

@ -10,9 +10,9 @@
#+BEGIN_SRC
[ᚢ ᛫ ᛫ ᛫
᛫ ᛫
᛫ ᛫
᛫ ᛫ ᛫ ]
᛫ ᛫
᛫ ᛫
᛫ ᛫ ᛫ ]
#+END_SRC
* Undâr
@ -94,29 +94,17 @@ heap allocations using the internal malloc opcode push pointers within this fram
#+BEGIN_SRC lisp
((code
(label main
(label main
(load-immediate $1 &hello-str) ; load hello string ptr
(push $1)
(call &pln)
(halt)) ; done
(label pln
(load-immediate $0 &terminal-namespace) ; get terminal device
(load-immediate $11 0)
(syscall OPEN $0 $0 $11)
(load-immediate $1 &help) ; print help message
(push $0)
(push $1)
(call &pln)
(load-immediate $1 32) ; read in a string of max 32 char length
(malloc $4 $1) ; allocate memory for the string
(load-offset-32 $7 $0 4) ; load handle
(syscall READ $7 $2 $1 $4) ; read the string
(push $0)
(push $4)
(call &pln) ; print the string
(halt))
(label pln
(syscall OPEN $0 $0 $11)
(load-immediate $3 &new-line)
(pop $1)
(pop $0)
(load-offset-32 $7 $0 4) ; load handle
(string-length $2 $1)
(syscall WRITE $7 $1 $2)
@ -125,8 +113,8 @@ heap allocations using the internal malloc opcode push pointers within this fram
(return)))
(data
(label terminal-namespace "/dev/term/0")
(label help "Enter a string: ")
(label new-line "\n")))
(label new-line "\n")
(label hello-str "nuqneH 'u'?")))
#+END_SRC
values passed to functions must be explicitly returned to propagate. heap values are copy on write, so if a value is modified in a child function it will change the parents value, unless the size of the structure changes then it will copy the parents value and append it to its own frame with the modification. this allows for the low resource usage of a C but the convenience of a Java/Go without the garbage collection.

View File

@ -10,12 +10,49 @@
* Roadmap
** Memory System Improvements
in the beta phase the bump allocator will be removed and replaced with the following system: instead of the bump allocator memory and registers being separate, the frames are in vm memory and then dynamically allocate a frame and register with a size each time a function gets called of a particular arena size. the syntax would be fnN where N is the number is the size in kb for that particular frame, however the compiler will split up the available memory for that architecture into function arenas of the defined "theoretical maximum" of running coroutines. the "maximum" is going to be whatever is hardcoded for the VM, like 1MB or 100MB or 1GB or whatever. The true max will be <4GB because that is all that can be addressed by a u32. the sizes we can say that for a particular architecture has n many 128kb function and y many 8kb functions and so on; then the compiler could partition the system and report that the program requires x of this many slots of this size and y slots of another size. for strings we will extend the syntax we can use str8 is 8 bytes or str16 is 16 bytes or whatever, that way we have a shorthand that is consistent with the rest of the language and is friendly to new developers; however we would keep array syntax the same as in c-like languages `<type>[size]`. the stack and return stack need to be removed as well; like imagine you push some value onto the stack and then switch coroutines and then in that one it pops or pushes that would break. instead we will have a tiny stack per frame for function arguments and have a "return register" to allocate where the function should return to when it finishes. if it gets called recursively it will just take up a new block of the same size. recursive calls should be discouraged in general for this reason, its not a good technique for embedded development or permacomputing. so yes, it *will* compile, but guarantee the compiler *will* make surreal comments about your code. The compiler output in general should have an [[esolangs.org/wiki/INTERCAL][INTERCAL]] feel to it; the compiler needs to not take itself too seriously, but that does not mean it should not give useful advice to the programmer.
** Actor System
** Coroutine System
* Actor-Based Concurrency Model (Frame-Managed Memory)
coroutine system that uses the yield keyword so that functions can run out of order. make all functions coroutines i.e. they should be first class objects in the vm. the system will work similar to a real time microkernel based os like qnx. when a coroutine yields the system will continue from the last function that was running, or it will continue in the "main function" which may spawn new coroutines. each call will allocate a new block in memory. there will also be a "behavior" system where a specific coroutine might have "restart on fail" where others might have "exit on fail" or still others might have "crash on fail", this allows for systems to react to changing external factors. in the long long term (post 1.0) i want to make coroutines similar to beam where they run mutithreaded an use mailboxes and message passing to communicate.
** Core Principles
- Deterministic memory management with no garbage collection or manual free
- Zero fragmentation via contiguous arena allocation
- Isolated memory spaces for all actors (no shared memory)
- Compile-time memory bounds enforcement
- Mission-critical certified (DO-178C Level A compliant)
** Memory Architecture
- Actor memory is partitioned into fixed-size arenas
- Two primary arenas:
- =Main Thread Arena= (top of memory)
- =Actor Arenas= (bottom-up allocation)
- Arena layout:
#+begin_src text
|---------------------| <-- Top of memory
| MAIN THREAD | (e.g., 8KB)
|---------------------| <-- Base address of actor pool
| ACTOR 1 (4KB) | <-- Preallocated at system startup
|---------------------|
| ACTOR 2 (2KB) | <-- Size specified by developer
|---------------------|
| ACTOR 3 (1KB) |
|---------------------| <-- Bottom of memory
#+end_src
*** Communication Protocol
- Bounded mailbox system
- Message flow:
1. Main thread sends via =send_message()=
2. Message copied into actor's mailbox
3. Actor processes in =on_message()= during next cycle
4. Actor sends response via =send_response()=
*** Failure Behaviors
| Behavior | Action | Certification Impact | Example Use Case |
|----------------|----------------------------|----------------------|--------------------------|
| =RESTART= | Reset arena offset to 0 | 2 artifacts | Network reconnection |
| =EXIT= | Free arena | 1 artifact | Session termination |
| =CRASH= | Halt entire VM | 1 artifact | Critical subsystem fail |
** Example: Hello world (=hello.ul=)

3
docs/convert.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
magick -background none -density 384 undar.svg -define icon:auto-resize favicon.ico
magick -background none -density 100 undar.svg -define icon:auto-resize undar.png

BIN
docs/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

BIN
docs/undar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

56
docs/undar.svg Normal file
View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="32mm"
height="32mm"
viewBox="0 0 32 32"
version="1.1"
id="svg1"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="undâr.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showguides="false"
inkscape:zoom="10.504938"
inkscape:cx="69.062756"
inkscape:cy="50.880831"
inkscape:window-width="1939"
inkscape:window-height="932"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#000000;stroke:#ffffff;stroke-width:0.259677;stroke-opacity:0.5"
d="M 9.8701612,2.1298382 H 2.1298382 V 29.870162 h 7.740323 V 27.874455 H 3.9914349 V 4.0257595 h 5.8787263 z"
id="path1" />
<path
style="fill:#000000;stroke:#ffffff;stroke-width:0.259677;stroke-opacity:0.5"
d="m 22.129839,2.1298386 h 7.740323 V 29.870161 h -7.740323 v -1.995707 h 5.878726 V 4.02576 h -5.878726 z"
id="path1-3" />
<path
d="m 9.9966523,7.2192166 c 0.00192,1.1921857 0,17.6324454 0,17.6324454 H 11.947933 V 10.838 c 0,0 6.10676,1.037363 7.80512,3.238279 0.180102,0.233395 0,10.775383 0,10.775383 h 1.951281 L 21.704,13.017 C 21.719643,11.169234 18.492009,9.5084126 16.302239,8.6458806 13.47112,7.5307272 9.9947373,6.0270309 9.9966523,7.2192166 Z"
style="stroke:#ffffff;stroke-width:0.292319;stroke-opacity:0.5"
id="path3"
sodipodi:nodetypes="zcccscccsz" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,732 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="159.448px"
height="94.120px"
viewBox="0 -2850 8809.5 5200"
version="1.1"
id="svg45"
sodipodi:docname="equation.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview45"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="5.5369495"
inkscape:cx="68.358941"
inkscape:cy="52.465713"
inkscape:window-width="1991"
inkscape:window-height="932"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="g30" />
<defs
id="defs1">
<path
id="MJX-5-NCM-N-23A1"
d="M614 1500L321 1500L321 0L387 0L387 1432L614 1432C636 1432 647 1443 647 1466C647 1485 633 1500 614 1500Z" />
<path
id="MJX-5-NCM-N-23A3"
d="M614 68L387 68L387 1500L321 1500L321 0L614 0C636 0 647 11 647 34C647 53 633 68 614 68Z" />
<path
id="MJX-5-NCM-N-23A2"
d="M321 0L387 0L387 1000L321 1000Z" />
<path
id="MJX-5-NCM-N-22C5"
d="M192 250C192 279 168 303 139 303C110 303 86 279 86 250C86 221 110 197 139 197C168 197 192 221 192 250Z" />
<path
id="MJX-5-NCM-N-23A4"
d="M280 0L346 0L346 1500L53 1500C31 1500 20 1489 20 1466C20 1443 31 1432 53 1432L280 1432Z" />
<path
id="MJX-5-NCM-N-23A6"
d="M53 0L346 0L346 1500L280 1500L280 68L53 68C31 68 20 57 20 34C20 11 31 0 53 0Z" />
<path
id="MJX-5-NCM-N-23A5"
d="M280 0L346 0L346 1000L280 1000Z" />
</defs>
<g
stroke="#FFFFFF"
fill="#FFFFFF"
stroke-width="0"
transform="scale(1,-1)"
id="g45">
<g
data-mml-node="math"
data-latex="\begin{bmatrix} ᚢ &amp; \cdot &amp; \cdot &amp; \cdot \\ \cdot &amp;&amp; \cdot &amp; \cdot \\ \cdot &amp; \cdot &amp;&amp; \cdot \\ \cdot &amp; \cdot &amp; \cdot &amp; ᚾ \end{bmatrix}"
data-semantic-structure="(37 0 (9 (2 1) (4 3) (6 5) (8 7)) (18 (11 10) (13 12) (15 14) (17 16)) (27 (20 19) (22 21) (24 23) (26 25)) (36 (29 28) (31 30) (33 32) (35 34)) 38)"
id="g44">
<g
data-mml-node="TeXAtom"
data-mjx-texclass="INNER"
data-latex-item="{bmatrix}"
data-latex="\begin{bmatrix} ᚢ &amp; \cdot &amp; \cdot &amp; \cdot \\ \cdot &amp;&amp; \cdot &amp; \cdot \\ \cdot &amp; \cdot &amp;&amp; \cdot \\ \cdot &amp; \cdot &amp; \cdot &amp; ᚾ \end{bmatrix}"
data-semantic-type="matrix"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:1"
data-semantic-id="37"
data-semantic-children="9,18,27,36"
data-semantic-content="0,38"
data-semantic-attributes="latex:\begin{bmatrix} ᚢ &amp; \cdot &amp; \cdot &amp; \cdot \\ \cdot &amp;&amp; \cdot &amp; \cdot \\ \cdot &amp; \cdot &amp;&amp; \cdot \\ \cdot &amp; \cdot &amp; \cdot &amp; ᚾ \end{bmatrix};texclass:INNER"
data-semantic-owns="0 9 18 27 36 38"
aria-level="0"
data-speech-node="true"
id="g43">
<g
data-mml-node="mo"
data-mjx-texclass="OPEN"
data-semantic-type="fence"
data-semantic-role="open"
data-semantic-annotation="depth:2"
data-semantic-id="0"
data-semantic-parent="37"
data-semantic-attributes="texclass:OPEN"
aria-level="1"
data-speech-node="true"
id="g3"
transform="translate(662.99988)">
<use
data-c="23A1"
xlink:href="#MJX-5-NCM-N-23A1"
transform="translate(0,1350)"
id="use1" />
<use
data-c="23A3"
xlink:href="#MJX-5-NCM-N-23A3"
transform="translate(0,-2350)"
id="use2" />
<svg
width="667"
height="2400"
y="-950"
x="0"
viewBox="0 600 667 2400"
version="1.1"
id="svg3">
<use
data-c="23A2"
xlink:href="#MJX-5-NCM-N-23A2"
transform="scale(1,3.6)"
id="use3" />
</svg>
</g>
<g
data-mml-node="mtable"
transform="matrix(0.86153012,0,0,1,1268.3375,0)"
id="g40">
<g
data-mml-node="mtr"
data-semantic-type="row"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:2"
data-semantic-id="9"
data-semantic-children="2,4,6,8"
data-semantic-parent="37"
data-semantic-owns="2 4 6 8"
aria-level="1"
data-speech-node="true"
transform="translate(0,2100)"
id="g12">
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="2"
data-semantic-children="1"
data-semantic-parent="9"
data-semantic-owns="1"
aria-level="2"
data-speech-node="true"
id="g5"
transform="translate(256.52028)">
<g
data-mml-node="mi"
data-latex="ᚢ"
data-semantic-type="identifier"
data-semantic-role="unknown"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="1"
data-semantic-parent="2"
data-semantic-attributes="latex:ᚢ"
aria-level="3"
data-speech-node="true"
id="g4">
<text
data-variant="italic"
transform="scale(1,-1)"
font-size="884px"
font-family="serif"
font-style="italic"
id="text3">ᚢ</text>
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="4"
data-semantic-children="3"
data-semantic-parent="9"
data-semantic-owns="3"
aria-level="2"
data-speech-node="true"
transform="translate(2587.6)"
id="g7">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="3"
data-semantic-parent="4"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g6">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use5" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="6"
data-semantic-children="5"
data-semantic-parent="9"
data-semantic-owns="5"
aria-level="2"
data-speech-node="true"
transform="translate(4698.1)"
id="g9">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="5"
data-semantic-parent="6"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g8">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use7" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="8"
data-semantic-children="7"
data-semantic-parent="9"
data-semantic-owns="7"
aria-level="2"
data-speech-node="true"
transform="translate(6555.1798)"
id="g11">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="7"
data-semantic-parent="8"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g10">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use9" />
</g>
</g>
</g>
<g
data-mml-node="mtr"
data-semantic-type="row"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:2"
data-semantic-id="18"
data-semantic-children="11,13,15,17"
data-semantic-parent="37"
data-semantic-owns="11 13 15 17"
aria-level="1"
data-speech-node="true"
transform="translate(0,700)"
id="g21">
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="11"
data-semantic-children="10"
data-semantic-parent="18"
data-semantic-owns="10"
aria-level="2"
data-speech-node="true"
transform="translate(463.5)"
id="g14">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="10"
data-semantic-parent="11"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g13">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use12" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="13"
data-semantic-children="12"
data-semantic-parent="18"
data-semantic-owns="12"
aria-level="2"
data-speech-node="true"
transform="translate(2461.5202)"
id="g16">
<g
data-mml-node="mi"
data-latex="ᚱ"
data-semantic-type="identifier"
data-semantic-role="unknown"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="12"
data-semantic-parent="13"
data-semantic-attributes="latex:ᚱ"
aria-level="3"
data-speech-node="true"
id="g15">
<text
data-variant="italic"
transform="scale(1,-1)"
font-size="884px"
font-family="serif"
font-style="italic"
id="text14">ᚱ</text>
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="15"
data-semantic-children="14"
data-semantic-parent="18"
data-semantic-owns="14"
aria-level="2"
data-speech-node="true"
transform="translate(4698.1)"
id="g18">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="14"
data-semantic-parent="15"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g17">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use16" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="17"
data-semantic-children="16"
data-semantic-parent="18"
data-semantic-owns="16"
aria-level="2"
data-speech-node="true"
transform="translate(6555.1798)"
id="g20">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="16"
data-semantic-parent="17"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g19">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use18" />
</g>
</g>
</g>
<g
data-mml-node="mtr"
data-semantic-type="row"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:2"
data-semantic-id="27"
data-semantic-children="20,22,24,26"
data-semantic-parent="37"
data-semantic-owns="20 22 24 26"
aria-level="1"
data-speech-node="true"
transform="translate(0,-700)"
id="g30">
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="20"
data-semantic-children="19"
data-semantic-parent="27"
data-semantic-owns="19"
aria-level="2"
data-speech-node="true"
transform="translate(463.5)"
id="g23">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="19"
data-semantic-parent="20"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g22">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use21" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="22"
data-semantic-children="21"
data-semantic-parent="27"
data-semantic-owns="21"
aria-level="2"
data-speech-node="true"
transform="translate(2587.6)"
id="g25">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="21"
data-semantic-parent="22"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g24">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use23" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="24"
data-semantic-children="23"
data-semantic-parent="27"
data-semantic-owns="23"
aria-level="2"
data-speech-node="true"
transform="translate(4504.7202)"
id="g27">
<g
data-mml-node="mi"
data-latex="ᛋ"
data-semantic-type="identifier"
data-semantic-role="unknown"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="23"
data-semantic-parent="24"
data-semantic-attributes="latex:ᛋ"
aria-level="3"
data-speech-node="true"
id="g26">
<text
data-variant="italic"
transform="scale(1,-1)"
font-size="884px"
font-family="serif"
font-style="italic"
id="text25">ᛋ</text>
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="26"
data-semantic-children="25"
data-semantic-parent="27"
data-semantic-owns="25"
aria-level="2"
data-speech-node="true"
transform="translate(6555.1798)"
id="g29">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="25"
data-semantic-parent="26"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g28">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use27" />
</g>
</g>
</g>
<g
data-mml-node="mtr"
data-semantic-type="row"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:2"
data-semantic-id="36"
data-semantic-children="29,31,33,35"
data-semantic-parent="37"
data-semantic-owns="29 31 33 35"
aria-level="1"
data-speech-node="true"
transform="translate(0,-2100)"
id="g39">
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="29"
data-semantic-children="28"
data-semantic-parent="36"
data-semantic-owns="28"
aria-level="2"
data-speech-node="true"
transform="translate(463.5)"
id="g32">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="28"
data-semantic-parent="29"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g31">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use30" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="31"
data-semantic-children="30"
data-semantic-parent="36"
data-semantic-owns="30"
aria-level="2"
data-speech-node="true"
transform="translate(2587.6)"
id="g34">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="30"
data-semantic-parent="31"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g33">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use32" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="33"
data-semantic-children="32"
data-semantic-parent="36"
data-semantic-owns="32"
aria-level="2"
data-speech-node="true"
transform="translate(4698.1)"
id="g36">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="32"
data-semantic-parent="33"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g35">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use34" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="35"
data-semantic-children="34"
data-semantic-parent="36"
data-semantic-owns="34"
aria-level="2"
data-speech-node="true"
transform="translate(6426)"
id="g38">
<g
data-mml-node="mi"
data-latex="ᚾ"
data-semantic-type="identifier"
data-semantic-role="unknown"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="34"
data-semantic-parent="35"
data-semantic-attributes="latex:ᚾ"
aria-level="3"
data-speech-node="true"
id="g37">
<text
data-variant="italic"
transform="scale(1,-1)"
font-size="884px"
font-family="serif"
font-style="italic"
id="text36">ᚾ</text>
</g>
</g>
</g>
</g>
<g
data-mml-node="mo"
data-mjx-texclass="CLOSE"
data-semantic-type="fence"
data-semantic-role="close"
data-semantic-annotation="depth:2"
data-semantic-id="38"
data-semantic-parent="37"
data-semantic-attributes="texclass:CLOSE"
aria-level="1"
data-speech-node="true"
transform="translate(7369)"
id="g42">
<use
data-c="23A4"
xlink:href="#MJX-5-NCM-N-23A4"
transform="translate(0,1350)"
id="use40" />
<use
data-c="23A6"
xlink:href="#MJX-5-NCM-N-23A6"
transform="translate(0,-2350)"
id="use41" />
<svg
width="667"
height="2400"
y="-950"
x="0"
viewBox="0 600 667 2400"
version="1.1"
id="svg42">
<use
data-c="23A5"
xlink:href="#MJX-5-NCM-N-23A5"
transform="scale(1,3.6)"
id="use42" />
</svg>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,732 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="159.448px"
height="94.120px"
viewBox="0 -2850 8809.5 5200"
version="1.1"
id="svg45"
sodipodi:docname="equation.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview45"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="5.5369495"
inkscape:cx="68.358941"
inkscape:cy="52.465713"
inkscape:window-width="1991"
inkscape:window-height="932"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="g30" />
<defs
id="defs1">
<path
id="MJX-5-NCM-N-23A1"
d="M614 1500L321 1500L321 0L387 0L387 1432L614 1432C636 1432 647 1443 647 1466C647 1485 633 1500 614 1500Z" />
<path
id="MJX-5-NCM-N-23A3"
d="M614 68L387 68L387 1500L321 1500L321 0L614 0C636 0 647 11 647 34C647 53 633 68 614 68Z" />
<path
id="MJX-5-NCM-N-23A2"
d="M321 0L387 0L387 1000L321 1000Z" />
<path
id="MJX-5-NCM-N-22C5"
d="M192 250C192 279 168 303 139 303C110 303 86 279 86 250C86 221 110 197 139 197C168 197 192 221 192 250Z" />
<path
id="MJX-5-NCM-N-23A4"
d="M280 0L346 0L346 1500L53 1500C31 1500 20 1489 20 1466C20 1443 31 1432 53 1432L280 1432Z" />
<path
id="MJX-5-NCM-N-23A6"
d="M53 0L346 0L346 1500L280 1500L280 68L53 68C31 68 20 57 20 34C20 11 31 0 53 0Z" />
<path
id="MJX-5-NCM-N-23A5"
d="M280 0L346 0L346 1000L280 1000Z" />
</defs>
<g
stroke="#000000"
fill="#000000"
stroke-width="0"
transform="scale(1,-1)"
id="g45">
<g
data-mml-node="math"
data-latex="\begin{bmatrix} ᚢ &amp; \cdot &amp; \cdot &amp; \cdot \\ \cdot &amp;&amp; \cdot &amp; \cdot \\ \cdot &amp; \cdot &amp;&amp; \cdot \\ \cdot &amp; \cdot &amp; \cdot &amp; ᚾ \end{bmatrix}"
data-semantic-structure="(37 0 (9 (2 1) (4 3) (6 5) (8 7)) (18 (11 10) (13 12) (15 14) (17 16)) (27 (20 19) (22 21) (24 23) (26 25)) (36 (29 28) (31 30) (33 32) (35 34)) 38)"
id="g44">
<g
data-mml-node="TeXAtom"
data-mjx-texclass="INNER"
data-latex-item="{bmatrix}"
data-latex="\begin{bmatrix} ᚢ &amp; \cdot &amp; \cdot &amp; \cdot \\ \cdot &amp;&amp; \cdot &amp; \cdot \\ \cdot &amp; \cdot &amp;&amp; \cdot \\ \cdot &amp; \cdot &amp; \cdot &amp; ᚾ \end{bmatrix}"
data-semantic-type="matrix"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:1"
data-semantic-id="37"
data-semantic-children="9,18,27,36"
data-semantic-content="0,38"
data-semantic-attributes="latex:\begin{bmatrix} ᚢ &amp; \cdot &amp; \cdot &amp; \cdot \\ \cdot &amp;&amp; \cdot &amp; \cdot \\ \cdot &amp; \cdot &amp;&amp; \cdot \\ \cdot &amp; \cdot &amp; \cdot &amp; ᚾ \end{bmatrix};texclass:INNER"
data-semantic-owns="0 9 18 27 36 38"
aria-level="0"
data-speech-node="true"
id="g43">
<g
data-mml-node="mo"
data-mjx-texclass="OPEN"
data-semantic-type="fence"
data-semantic-role="open"
data-semantic-annotation="depth:2"
data-semantic-id="0"
data-semantic-parent="37"
data-semantic-attributes="texclass:OPEN"
aria-level="1"
data-speech-node="true"
id="g3"
transform="translate(662.99988)">
<use
data-c="23A1"
xlink:href="#MJX-5-NCM-N-23A1"
transform="translate(0,1350)"
id="use1" />
<use
data-c="23A3"
xlink:href="#MJX-5-NCM-N-23A3"
transform="translate(0,-2350)"
id="use2" />
<svg
width="667"
height="2400"
y="-950"
x="0"
viewBox="0 600 667 2400"
version="1.1"
id="svg3">
<use
data-c="23A2"
xlink:href="#MJX-5-NCM-N-23A2"
transform="scale(1,3.6)"
id="use3" />
</svg>
</g>
<g
data-mml-node="mtable"
transform="matrix(0.86153012,0,0,1,1268.3375,0)"
id="g40">
<g
data-mml-node="mtr"
data-semantic-type="row"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:2"
data-semantic-id="9"
data-semantic-children="2,4,6,8"
data-semantic-parent="37"
data-semantic-owns="2 4 6 8"
aria-level="1"
data-speech-node="true"
transform="translate(0,2100)"
id="g12">
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="2"
data-semantic-children="1"
data-semantic-parent="9"
data-semantic-owns="1"
aria-level="2"
data-speech-node="true"
id="g5"
transform="translate(256.52028)">
<g
data-mml-node="mi"
data-latex="ᚢ"
data-semantic-type="identifier"
data-semantic-role="unknown"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="1"
data-semantic-parent="2"
data-semantic-attributes="latex:ᚢ"
aria-level="3"
data-speech-node="true"
id="g4">
<text
data-variant="italic"
transform="scale(1,-1)"
font-size="884px"
font-family="serif"
font-style="italic"
id="text3">ᚢ</text>
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="4"
data-semantic-children="3"
data-semantic-parent="9"
data-semantic-owns="3"
aria-level="2"
data-speech-node="true"
transform="translate(2587.6)"
id="g7">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="3"
data-semantic-parent="4"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g6">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use5" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="6"
data-semantic-children="5"
data-semantic-parent="9"
data-semantic-owns="5"
aria-level="2"
data-speech-node="true"
transform="translate(4698.1)"
id="g9">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="5"
data-semantic-parent="6"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g8">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use7" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="8"
data-semantic-children="7"
data-semantic-parent="9"
data-semantic-owns="7"
aria-level="2"
data-speech-node="true"
transform="translate(6555.1798)"
id="g11">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="7"
data-semantic-parent="8"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g10">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use9" />
</g>
</g>
</g>
<g
data-mml-node="mtr"
data-semantic-type="row"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:2"
data-semantic-id="18"
data-semantic-children="11,13,15,17"
data-semantic-parent="37"
data-semantic-owns="11 13 15 17"
aria-level="1"
data-speech-node="true"
transform="translate(0,700)"
id="g21">
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="11"
data-semantic-children="10"
data-semantic-parent="18"
data-semantic-owns="10"
aria-level="2"
data-speech-node="true"
transform="translate(463.5)"
id="g14">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="10"
data-semantic-parent="11"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g13">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use12" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="13"
data-semantic-children="12"
data-semantic-parent="18"
data-semantic-owns="12"
aria-level="2"
data-speech-node="true"
transform="translate(2461.5202)"
id="g16">
<g
data-mml-node="mi"
data-latex="ᚱ"
data-semantic-type="identifier"
data-semantic-role="unknown"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="12"
data-semantic-parent="13"
data-semantic-attributes="latex:ᚱ"
aria-level="3"
data-speech-node="true"
id="g15">
<text
data-variant="italic"
transform="scale(1,-1)"
font-size="884px"
font-family="serif"
font-style="italic"
id="text14">ᚱ</text>
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="15"
data-semantic-children="14"
data-semantic-parent="18"
data-semantic-owns="14"
aria-level="2"
data-speech-node="true"
transform="translate(4698.1)"
id="g18">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="14"
data-semantic-parent="15"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g17">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use16" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="17"
data-semantic-children="16"
data-semantic-parent="18"
data-semantic-owns="16"
aria-level="2"
data-speech-node="true"
transform="translate(6555.1798)"
id="g20">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="16"
data-semantic-parent="17"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g19">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use18" />
</g>
</g>
</g>
<g
data-mml-node="mtr"
data-semantic-type="row"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:2"
data-semantic-id="27"
data-semantic-children="20,22,24,26"
data-semantic-parent="37"
data-semantic-owns="20 22 24 26"
aria-level="1"
data-speech-node="true"
transform="translate(0,-700)"
id="g30">
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="20"
data-semantic-children="19"
data-semantic-parent="27"
data-semantic-owns="19"
aria-level="2"
data-speech-node="true"
transform="translate(463.5)"
id="g23">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="19"
data-semantic-parent="20"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g22">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use21" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="22"
data-semantic-children="21"
data-semantic-parent="27"
data-semantic-owns="21"
aria-level="2"
data-speech-node="true"
transform="translate(2587.6)"
id="g25">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="21"
data-semantic-parent="22"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g24">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use23" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="24"
data-semantic-children="23"
data-semantic-parent="27"
data-semantic-owns="23"
aria-level="2"
data-speech-node="true"
transform="translate(4504.7202)"
id="g27">
<g
data-mml-node="mi"
data-latex="ᛋ"
data-semantic-type="identifier"
data-semantic-role="unknown"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="23"
data-semantic-parent="24"
data-semantic-attributes="latex:ᛋ"
aria-level="3"
data-speech-node="true"
id="g26">
<text
data-variant="italic"
transform="scale(1,-1)"
font-size="884px"
font-family="serif"
font-style="italic"
id="text25">ᛋ</text>
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="26"
data-semantic-children="25"
data-semantic-parent="27"
data-semantic-owns="25"
aria-level="2"
data-speech-node="true"
transform="translate(6555.1798)"
id="g29">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="25"
data-semantic-parent="26"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g28">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use27" />
</g>
</g>
</g>
<g
data-mml-node="mtr"
data-semantic-type="row"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:2"
data-semantic-id="36"
data-semantic-children="29,31,33,35"
data-semantic-parent="37"
data-semantic-owns="29 31 33 35"
aria-level="1"
data-speech-node="true"
transform="translate(0,-2100)"
id="g39">
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="29"
data-semantic-children="28"
data-semantic-parent="36"
data-semantic-owns="28"
aria-level="2"
data-speech-node="true"
transform="translate(463.5)"
id="g32">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="28"
data-semantic-parent="29"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g31">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use30" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="31"
data-semantic-children="30"
data-semantic-parent="36"
data-semantic-owns="30"
aria-level="2"
data-speech-node="true"
transform="translate(2587.6)"
id="g34">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="30"
data-semantic-parent="31"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g33">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use32" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="33"
data-semantic-children="32"
data-semantic-parent="36"
data-semantic-owns="32"
aria-level="2"
data-speech-node="true"
transform="translate(4698.1)"
id="g36">
<g
data-mml-node="mo"
data-latex="\cdot"
data-semantic-type="operator"
data-semantic-role="multiplication"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="32"
data-semantic-parent="33"
data-semantic-attributes="latex:\cdot"
aria-level="3"
data-speech-node="true"
id="g35">
<use
data-c="22C5"
xlink:href="#MJX-5-NCM-N-22C5"
id="use34" />
</g>
</g>
<g
data-mml-node="mtd"
data-semantic-type="cell"
data-semantic-role="squarematrix"
data-semantic-annotation="depth:3"
data-semantic-id="35"
data-semantic-children="34"
data-semantic-parent="36"
data-semantic-owns="34"
aria-level="2"
data-speech-node="true"
transform="translate(6426)"
id="g38">
<g
data-mml-node="mi"
data-latex="ᚾ"
data-semantic-type="identifier"
data-semantic-role="unknown"
data-semantic-annotation="nemeth:number;depth:4"
data-semantic-id="34"
data-semantic-parent="35"
data-semantic-attributes="latex:ᚾ"
aria-level="3"
data-speech-node="true"
id="g37">
<text
data-variant="italic"
transform="scale(1,-1)"
font-size="884px"
font-family="serif"
font-style="italic"
id="text36">ᚾ</text>
</g>
</g>
</g>
</g>
<g
data-mml-node="mo"
data-mjx-texclass="CLOSE"
data-semantic-type="fence"
data-semantic-role="close"
data-semantic-annotation="depth:2"
data-semantic-id="38"
data-semantic-parent="37"
data-semantic-attributes="texclass:CLOSE"
aria-level="1"
data-speech-node="true"
transform="translate(7369)"
id="g42">
<use
data-c="23A4"
xlink:href="#MJX-5-NCM-N-23A4"
transform="translate(0,1350)"
id="use40" />
<use
data-c="23A6"
xlink:href="#MJX-5-NCM-N-23A6"
transform="translate(0,-2350)"
id="use41" />
<svg
width="667"
height="2400"
y="-950"
x="0"
viewBox="0 600 667 2400"
version="1.1"
id="svg42">
<use
data-c="23A5"
xlink:href="#MJX-5-NCM-N-23A5"
transform="scale(1,3.6)"
id="use42" />
</svg>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -123,7 +123,6 @@ bool loadVM(const char *filename, VM *vm) {
fread(&vm->cp, sizeof(u32), 1, file) != 1 ||
fread(&vm->fp, sizeof(u32), 1, file) != 1 ||
fread(&vm->sp, sizeof(u32), 1, file) != 1 ||
fread(&vm->rp, sizeof(u32), 1, file) != 1 ||
fread(&vm->mp, sizeof(u32), 1, file) != 1 ||
fread(&vm->dc, sizeof(u32), 1, file) != 1 ||
fread(&vm->flag, sizeof(i32), 1, file) != 1) {

View File

@ -55,7 +55,6 @@ bool saveVM(const char *filename, VM *vm) {
fwrite(&vm->cp, sizeof(u32), 1, file) != 1 ||
fwrite(&vm->fp, sizeof(u32), 1, file) != 1 ||
fwrite(&vm->sp, sizeof(u32), 1, file) != 1 ||
fwrite(&vm->rp, sizeof(u32), 1, file) != 1 ||
fwrite(&vm->mp, sizeof(u32), 1, file) != 1 ||
fwrite(&vm->dc, sizeof(u32), 1, file) != 1 ||
fwrite(&vm->flag, sizeof(i32), 1, file) != 1) {
@ -94,7 +93,6 @@ bool loadVM(const char *filename, VM *vm) {
fread(&vm->cp, sizeof(u32), 1, file) != 1 ||
fread(&vm->fp, sizeof(u32), 1, file) != 1 ||
fread(&vm->sp, sizeof(u32), 1, file) != 1 ||
fread(&vm->rp, sizeof(u32), 1, file) != 1 ||
fread(&vm->mp, sizeof(u32), 1, file) != 1 ||
fread(&vm->dc, sizeof(u32), 1, file) != 1 ||
fread(&vm->flag, sizeof(i32), 1, file) != 1) {
@ -440,7 +438,7 @@ i32 main(i32 argc, char *argv[]) {
if (ext && (strcmp(ext, ".rom") == 0)) {
is_rom = true;
}
if (ext && (strcmp(ext, ".asm.lisp") == 0)) {
if (ext && (strcmp(ext, ".lisp") == 0)) {
is_assembly = true;
}
} else if (output_file == nil && dump_rom) {
@ -587,7 +585,7 @@ i32 main(i32 argc, char *argv[]) {
// Run VM for a fixed number of cycles or a time slice
int cycles_this_frame = 0;
int max_cycles_per_frame = 1000; // Adjust this value
int max_cycles_per_frame = 100; // Adjust this value
while (cycles_this_frame < max_cycles_per_frame) {
#ifdef ASM_DEBUG
printf("| %s %d\n", opcode_to_string(vm.code[vm.pc]),vm.pc);

View File

@ -1,4 +1,5 @@
#include "assembler.h"
#include "parser.h"
typedef enum { SYMBOL_CODE, SYMBOL_DATA } SymbolType;
typedef struct {
@ -66,25 +67,33 @@ int get_instruction_byte_size(ExprNode *node) {
const char *opname = node->token;
// Simple opcodes (1 byte)
if (strcmp(opname, "halt") == 0 || strcmp(opname, "return") == 0) {
if (strcmp(opname, "halt") == 0) {
return 1;
}
// Register-based opcodes (2 bytes: opcode + register)
if (strcmp(opname, "pop") == 0 || strcmp(opname, "push") == 0) {
return 2;
// Return (1 + 1)
if (strcmp(opname, "return") == 0) {
return 2; // 1 byte opcode + 1 byte return register
}
if (strcmp(opname, "int-to-string") == 0 || strcmp(opname, "load-indirect-8") == 0 ||
strcmp(opname, "nat-to-string") == 0 || strcmp(opname, "load-indirect-16") == 0 ||
strcmp(opname, "real-to-string") == 0 || strcmp(opname, "load-indirect-32") == 0 ||
strcmp(opname, "int-to-real") == 0 || strcmp(opname, "store-indirect-8") == 0 ||
strcmp(opname, "nat-to-real") == 0 || strcmp(opname, "store-indirect-16") == 0 ||
strcmp(opname, "real-to-int") == 0 || strcmp(opname, "store-indirect-32") == 0 ||
strcmp(opname, "real-to-nat") == 0 ||
strcmp(opname, "nat-to-int") == 0 || strcmp(opname, "int-to-nat") == 0 ||
strcmp(opname, "string-length") == 0 || strcmp(opname, "store-absolute-32") == 0 ||
strcmp(opname, "store-absolute-8") == 0 || strcmp(opname, "store-absolute-16") == 0 ||
if (strcmp(opname, "int-to-string") == 0 ||
strcmp(opname, "load-indirect-8") == 0 ||
strcmp(opname, "nat-to-string") == 0 ||
strcmp(opname, "load-indirect-16") == 0 ||
strcmp(opname, "real-to-string") == 0 ||
strcmp(opname, "load-indirect-32") == 0 ||
strcmp(opname, "int-to-real") == 0 ||
strcmp(opname, "store-indirect-8") == 0 ||
strcmp(opname, "nat-to-real") == 0 ||
strcmp(opname, "store-indirect-16") == 0 ||
strcmp(opname, "real-to-int") == 0 ||
strcmp(opname, "store-indirect-32") == 0 ||
strcmp(opname, "real-to-nat") == 0 || strcmp(opname, "nat-to-int") == 0 ||
strcmp(opname, "int-to-nat") == 0 ||
strcmp(opname, "string-length") == 0 ||
strcmp(opname, "store-absolute-32") == 0 ||
strcmp(opname, "store-absolute-8") == 0 ||
strcmp(opname, "store-absolute-16") == 0 ||
strcmp(opname, "memset") == 0 || strcmp(opname, "memset") == 0 ||
strcmp(opname, "memset-8") == 0 || strcmp(opname, "memset-16") == 0 ||
strcmp(opname, "register-move") == 0 || strcmp(opname, "malloc") == 0) {
@ -97,7 +106,8 @@ int get_instruction_byte_size(ExprNode *node) {
strcmp(opname, "add-nat") == 0 || strcmp(opname, "sub-nat") == 0 ||
strcmp(opname, "mul-nat") == 0 || strcmp(opname, "div-nat") == 0 ||
strcmp(opname, "add-real") == 0 || strcmp(opname, "sub-real") == 0 ||
strcmp(opname, "bit-shift-left") == 0 || strcmp(opname, "bit-shift-right") == 0 ||
strcmp(opname, "bit-shift-left") == 0 ||
strcmp(opname, "bit-shift-right") == 0 ||
strcmp(opname, "bit-and") == 0 || strcmp(opname, "bit-or") == 0 ||
strcmp(opname, "bit-xor") == 0 || strcmp(opname, "mul-real") == 0 ||
strcmp(opname, "div-real") == 0) {
@ -105,14 +115,15 @@ int get_instruction_byte_size(ExprNode *node) {
}
// (5 bytes: 1 + 4)
if (strcmp(opname, "call") == 0 || strcmp(opname, "jump-if-flag") == 0 ||
strcmp(opname, "jump") == 0) {
if (strcmp(opname, "jump-if-flag") == 0 || strcmp(opname, "jump") == 0) {
return 5;
}
// Load, Load-immediate (6 bytes: 1 + 1 + 4)
if (strcmp(opname, "load-absolute-32") == 0 || strcmp(opname, "load-immediate") == 0 ||
strcmp(opname, "load-absolute-16") == 0 || strcmp(opname, "load-absolute-8") == 0) {
if (strcmp(opname, "load-absolute-32") == 0 ||
strcmp(opname, "load-immediate") == 0 ||
strcmp(opname, "load-absolute-16") == 0 ||
strcmp(opname, "load-absolute-8") == 0) {
return 6;
}
@ -139,11 +150,31 @@ int get_instruction_byte_size(ExprNode *node) {
strcmp(opname, "store-offset-16") == 0 ||
strcmp(opname, "store-offset-32") == 0 ||
strcmp(opname, "load-offset-8") == 0 ||
strcmp(opname, "load-offset-16") == 0 ||
strcmp(opname, "load-offset-16") == 0 ||
strcmp(opname, "load-offset-32") == 0) {
return 7;
}
// Call (1 + 4 + 1 + args + 1)
if (strcmp(opname, "call") == 0) {
ExprNode *args_node = node->children[1];
u32 args_count;
// Calculate actual argument count
if (strcmp(args_node->token, "nil") == 0) {
args_count = 0;
} else {
args_count = 1 + args_node->child_count;
}
// Binary format:
// [1] OP_CALL
// [1] arg_count
// [1] return_reg
// [4] address
// [args_count] arguments (each 1 byte)
return 1 + 1 + 1 + 4 + args_count;
}
// Syscall (1 + syscall_id (4) + args)
if (strcmp(opname, "syscall") == 0) {
@ -431,10 +462,95 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) {
emit_u32(vm, addr);
} else if (strcmp(opname, "call") == 0) {
emit_opcode(vm, OP_CALL);
if (node->child_count < 3) {
fprintf(stderr, "Error: call requires (args) and return register\n");
return;
}
// Parse function address (first child)
u32 addr = resolve_symbol(table, node->children[0]->token);
if (addr == (u32)-1) {
fprintf(stderr, "Error: undefined symbol '%s'\n",
node->children[0]->token);
return;
}
emit_u32(vm, addr);
} else if (strcmp(opname, "return") == 0) {
emit_opcode(vm, OP_RETURN);
// Parse argument list (second child)
ExprNode *args_node = node->children[1];
u8 arg_count = 0;
// Handle two possible representations:
// 1. Single element: represented as a node with token (child_count=0)
// 2. Multiple elements: represented as node with children (child_count>0)
if (args_node->child_count > 0) {
// Multiple arguments case
arg_count = args_node->child_count + 1; // +1 for the token
} else {
// Single argument case - token is the argument
arg_count = (args_node->token[0] != '\0') ? 1 : 0;
}
emit_byte(vm, arg_count);
// Emit arguments based on representation
if (arg_count > 0) {
// First argument is always the token
const char *reg_str = args_node->token;
int reg = parse_register(reg_str);
if (reg < 0) {
fprintf(stderr, "Error: invalid argument register '%s'\n", reg_str);
return;
}
emit_byte(vm, (u8)reg);
// Emit children if present
for (size_t i = 0; i < args_node->child_count; i++) {
reg_str = args_node->children[i]->token;
reg = parse_register(reg_str);
if (reg < 0) {
fprintf(stderr, "Error: invalid argument register '%s'\n", reg_str);
return;
}
emit_byte(vm, (u8)reg);
}
}
// Parse return register (third child)
const char *return_reg_str = node->children[2]->token;
int return_reg = parse_register(return_reg_str);
if (return_reg < 0) {
if (strcmp(return_reg_str, "nil") == 0) {
return_reg = 0xFF;
} else {
fprintf(stderr, "Error: invalid return register '%s'\n",
return_reg_str);
return;
}
}
emit_byte(vm, (u8)return_reg);
} else if (strcmp(opname, "return") == 0) {
emit_opcode(vm, OP_RETURN);
if (node->child_count != 1) {
fprintf(stderr, "Error: return requires exactly one argument\n");
return;
}
const char *reg_str = node->children[0]->token;
int reg = parse_register(reg_str);
// Handle "nil" as special case (no return value)
if (reg < 0) {
if (strcmp(reg_str, "nil") == 0) {
reg = 0xFF; // Special value for "no return"
} else {
fprintf(stderr, "Error: invalid return register '%s'\n", reg_str);
return;
}
}
emit_byte(vm, (u8)reg);
} else if (strcmp(opname, "load-immediate") == 0) {
emit_opcode(vm, OP_LOAD_IMM);
int reg = parse_register(node->children[0]->token);
@ -591,14 +707,6 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) {
emit_byte(vm, dest);
emit_byte(vm, src1);
emit_u32(vm, addr);
} else if (strcmp(opname, "push") == 0) {
emit_opcode(vm, OP_PUSH);
int reg = parse_register(node->children[0]->token);
emit_byte(vm, reg);
} else if (strcmp(opname, "pop") == 0) {
emit_opcode(vm, OP_POP);
int reg = parse_register(node->children[0]->token);
emit_byte(vm, reg);
} else if (strcmp(opname, "register-move") == 0) {
emit_opcode(vm, OP_REG_MOV);
int dest = parse_register(node->children[0]->token);

View File

@ -32,8 +32,6 @@ typedef enum {
OP_MEMSET_8, /* memset-8 : dest <-> dest+count = src1 as u8 */
OP_MEMSET_16, /* memset-16 : dest <-> dest+count = src1 as u8 */
OP_MEMSET_32, /* memset-32 : dest <-> dest+count = src1 as u32 */
OP_PUSH, /* push : push const or ref */
OP_POP, /* pop : pop cosnt or ref */
OP_REG_MOV, /* register-move : dest = src1 */
OP_SYSCALL, /* syscall : src1 src2 src3 src4 more? does a system call based on args */
OP_SLL, /* bit-shift-left : registers[dest] = registers[src1] << registers[src2] */
@ -93,9 +91,10 @@ typedef enum {
#define MAX_REGS 32
typedef struct frame_s {
u32 registers[MAX_REGS]; /* R0-R31 */
u32 rp; /* register pointer (last unused) */
u32 start; /* start and end of global allocated block */
u32 end;
u32 start; /* start of memory block */
u32 end; /* end of memory block */
u32 return_reg; /* register to store return value in parent */
u32 heap_mask; /* bitfield: 1 bit per register (R0=bit0, R1=bit1, etc) */
} Frame;
typedef enum {
@ -140,13 +139,11 @@ typedef struct vm_s {
u32 cp; /* code pointer (last allocated opcode) */
u32 fp; /* frame pointer (current frame) */
u32 sp; /* stack pointer (top of stack) */
u32 rp; /* return stack pointer (top of stack) */
u32 mp; /* memory pointer (last allocated value) */
u32 dc; /* device count */
i32 flag; /* flag (temporary results like SYSCALL status) */
Frame frames[FRAMES_SIZE]; /* function call frames */
u32 stack[STACK_SIZE]; /* main stack */
u32 return_stack[STACK_SIZE]; /* return stack (for call recursion) */
Device devices[DEVICES_SIZE]; /* device definitions */
u8 code[CODE_SIZE]; /* code block */
u8 memory[MEMORY_SIZE]; /* memory block */

View File

@ -49,6 +49,20 @@
return true; \
} while (0)
/* Set heap status for a register in current frame */
void set_heap_status(VM *vm, u8 reg, bool is_heap) {
if (is_heap) {
vm->frames[vm->fp].heap_mask |= (1 << reg);
} else {
vm->frames[vm->fp].heap_mask &= ~(1 << reg);
}
}
/* Check if register contains heap pointer */
bool is_heap_value(VM *vm, u8 reg) {
return (vm->frames[vm->fp].heap_mask >> reg) & 1;
}
u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length) {
u32 str_addr = vm->mp;
u32 i = 0;
@ -81,20 +95,89 @@ bool step_vm(VM *vm) {
return false;
}
case OP_CALL: {
i32 i;
u8 N, return_reg, args[MAX_REGS];
Frame *child;
u32 jmp = read_u32(vm, code, vm->pc); /* location of function in code */
vm->pc += 4;
vm->return_stack[vm->rp++] = vm->pc; /* set return address */
vm->fp++; /* increment to the next free frame */
vm->frames[vm->fp].start = vm->mp; /* set start of new memory block */
N = vm->code[vm->pc++]; /* Number of arguments */
for (i = 0; i < N; i++) {
args[i] = vm->code[vm->pc++];
}
return_reg = vm->code[vm->pc++];
frame->return_reg = return_reg; /* Set current frame's return register */
if (vm->sp >= STACK_SIZE)
return false;
vm->stack[vm->sp++] = vm->pc; /* set return address */
if (vm->fp >= FRAMES_SIZE - 1)
return false;
vm->fp++; /* increment to the next free frame */
child = &vm->frames[vm->fp];
child->start = vm->mp; /* set start of new memory block */
child->end = vm->mp;
child->return_reg = 0;
child->heap_mask = 0;
for (i = 0; i < N; i++) {
u8 src_reg = args[i];
child->registers[i] = frame->registers[src_reg];
if (frame->heap_mask & (1 << src_reg)) {
child->heap_mask |= (1 << i);
}
}
vm->pc = jmp;
return true;
}
case OP_RETURN: {
frame->rp = 0; /* reset register ptr */
vm->pc = vm->return_stack[--vm->rp]; /* set pc to return address */
vm->mp =
vm->frames[vm->fp--].start; /* reset memory pointer to start
of old slice, pop the frame */
u32 ptr, new_ptr, size, value, i;
Frame *child = frame;
Frame *parent = &vm->frames[vm->fp - 1];
u8 child_return_reg = vm->code[vm->pc++];
if (child_return_reg != 0xFF) {
value = child->registers[child_return_reg];
if (is_heap_value(vm, child_return_reg)) {
ptr = value;
size = *(u32 *)(vm->memory + ptr - 4);
/* Allocate and copy in parent's frame */
new_ptr = parent->end;
if (parent->end + size + 4 > MEMORY_SIZE)
return false;
*(u32 *)(vm->memory + new_ptr) = size;
for (i = 0; i < size - 1; i++) {
(vm->memory + new_ptr + 4)[i] = (vm->memory + ptr + 4)[i];
}
parent->end += size + 4;
/* Update parent's register */
parent->registers[parent->return_reg] = new_ptr;
parent->heap_mask |= (1 << parent->return_reg);
} else {
/* Non-heap return value */
parent->registers[parent->return_reg] = value;
parent->heap_mask &= ~(1 << parent->return_reg);
}
} else {
/* If returning "nil",
clear heap bit for parent's return register if valid */
if (parent->return_reg != 0xFF) {
parent->heap_mask &= ~(1 << parent->return_reg);
}
}
vm->pc = vm->stack[--vm->sp]; /* set pc to return address */
vm->mp = child->start; /* reset memory pointer to start
of old slice, pop the frame */
vm->fp--;
return true;
}
case OP_MALLOC: {
@ -107,6 +190,7 @@ bool step_vm(VM *vm) {
size = frame->registers[src1];
write_u32(vm, memory, vm->mp, size);
vm->mp += (size + 4);
set_heap_status(vm, dest, true); /* Mark as heap pointer */
return true;
}
case OP_MEMSET_32: {
@ -114,7 +198,7 @@ bool step_vm(VM *vm) {
u8 dest_reg = read_u8(vm, code, vm->pc++);
u8 value_reg = read_u8(vm, code, vm->pc++);
u8 count_reg = read_u8(vm, code, vm->pc++);
u32 dest = frame->registers[dest_reg];
u32 value = frame->registers[value_reg];
u32 count = frame->registers[count_reg];
@ -127,13 +211,12 @@ bool step_vm(VM *vm) {
start = dest;
end = dest + count;
if (start >= vm->mp || count > vm->mp ||
end > vm->mp) {
if (start >= vm->mp || count > vm->mp || end > vm->mp) {
vm->flag = 0;
return true;
}
for (i = start; i < end; i+=4) {
for (i = start; i < end; i += 4) {
write_u32(vm, memory, i, value);
}
@ -146,7 +229,7 @@ bool step_vm(VM *vm) {
u8 dest_reg = read_u8(vm, code, vm->pc++);
u8 value_reg = read_u8(vm, code, vm->pc++);
u8 count_reg = read_u8(vm, code, vm->pc++);
u32 dest = frame->registers[dest_reg];
u16 value = (u16)(frame->registers[value_reg]);
u32 count = frame->registers[count_reg];
@ -159,13 +242,12 @@ bool step_vm(VM *vm) {
start = dest;
end = dest + count;
if (start >= vm->mp || count > vm->mp ||
end > vm->mp) {
if (start >= vm->mp || count > vm->mp || end > vm->mp) {
vm->flag = 0;
return true;
}
for (i = start; i < end; i+=2) {
for (i = start; i < end; i += 2) {
write_u16(vm, memory, i, value);
}
@ -178,7 +260,7 @@ bool step_vm(VM *vm) {
u8 dest_reg = read_u8(vm, code, vm->pc++);
u8 value_reg = read_u8(vm, code, vm->pc++);
u8 count_reg = read_u8(vm, code, vm->pc++);
u32 dest = frame->registers[dest_reg];
u8 value = (u8)(frame->registers[value_reg]);
u32 count = frame->registers[count_reg];
@ -191,8 +273,7 @@ bool step_vm(VM *vm) {
start = dest;
end = dest + count;
if (start >= vm->mp || count > vm->mp ||
end > vm->mp) {
if (start >= vm->mp || count > vm->mp || end > vm->mp) {
vm->flag = 0;
return true;
}
@ -349,8 +430,8 @@ bool step_vm(VM *vm) {
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = frame->registers[dest];
v = frame->registers[src1];
write_u32(vm, memory, ptr, v);
v = frame->registers[src1];
write_u32(vm, memory, ptr, v);
return true;
}
case OP_STORE_IND_16: {
@ -412,20 +493,8 @@ bool step_vm(VM *vm) {
offset = read_u32(vm, code, vm->pc);
vm->pc += 4;
ptr = frame->registers[dest];
v = frame->registers[src1];
write_u32(vm, memory, (ptr + offset), v);
return true;
}
case OP_PUSH: {
dest = read_u8(vm, code, vm->pc);
vm->pc++;
vm->stack[++vm->sp] = frame->registers[dest];
return true;
}
case OP_POP: {
dest = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] = vm->stack[vm->sp--];
v = frame->registers[src1];
write_u32(vm, memory, (ptr + offset), v);
return true;
}
case OP_REG_MOV: {
@ -434,6 +503,13 @@ bool step_vm(VM *vm) {
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] = frame->registers[src1];
if (is_heap_value(vm, src1)) {
set_heap_status(vm, dest, true);
} else {
set_heap_status(vm, dest, false);
}
return true;
}
case OP_JMP: {
@ -478,7 +554,8 @@ bool step_vm(VM *vm) {
write_u32(vm, memory, buffer_ptr, dev->size);
vm->mp += (dev->size + 4);
/* set flag from user */
vm->flag = dev->ops->open(dev->data, mode, dev->handle, &vm->memory[buffer_ptr + 4], dev->size);
vm->flag = dev->ops->open(dev->data, mode, dev->handle,
&vm->memory[buffer_ptr + 4], dev->size);
} else {
vm->flag = 1; /* success, no open needed */
}

View File

@ -1,35 +1,27 @@
((code
(label main
(load-immediate $0 1)
(push $0)
(load-immediate $0 1)
(push $0)
(call &add)
(pop $0)
(int-to-string $1 $0)
(push $1)
(call &pln)
(load-immediate $1 1)
(call &add ($0 $1) $2)
(int-to-string $3 $2)
(call &pln ($3) nil)
(halt))
(label add
(pop $0)
(pop $1)
(add-int $2 $1 $0)
(push $2)
(return))
(return $2))
(label pln
(load-immediate $0 &terminal-namespace) ; get terminal device
(load-immediate $1 &terminal-namespace) ; get terminal device
(load-immediate $11 0)
(syscall OPEN $0 $0 $11)
(syscall OPEN $1 $1 $11)
(load-immediate $3 &new-line)
(pop $1)
(load-offset-32 $7 $0 4) ; load handle
(string-length $2 $1)
(syscall WRITE $7 $1 $2)
(load-offset-32 $7 $1 4) ; load handle
(string-length $2 $0)
(syscall WRITE $7 $0 $2)
(string-length $4 $3)
(syscall WRITE $7 $3 $4)
(return)))
(return nil)))
(data
(label terminal-namespace "/dev/term/0")
(label new-line "\n")))

View File

@ -1,21 +1,19 @@
((code
(label main
(load-immediate $1 &hello-str) ; load hello string ptr
(push $1)
(call &pln)
(call &pln ($1) nil)
(halt)) ; done
(label pln
(load-immediate $0 &terminal-namespace) ; get terminal device
(load-immediate $1 &terminal-namespace) ; get terminal device
(load-immediate $11 0)
(syscall OPEN $0 $0 $11)
(syscall OPEN $1 $1 $11)
(load-immediate $3 &new-line)
(pop $1)
(load-offset-32 $7 $0 4) ; load handle
(string-length $2 $1)
(syscall WRITE $7 $1 $2)
(load-offset-32 $7 $1 4) ; load handle
(string-length $2 $0)
(syscall WRITE $7 $0 $2)
(string-length $4 $3)
(syscall WRITE $7 $3 $4)
(return)))
(return nil)))
(data
(label terminal-namespace "/dev/term/0")
(label new-line "\n")

View File

@ -18,27 +18,23 @@
(malloc $11 $8)
(syscall READ $10 $2 $8 $11)
(push $2)
(call &pln)
(call &pln ($2) nil)
(nat-to-string $4 $1)
(push $4)
(call &pln)
(call &pln ($4) nil)
(real-to-string $3 $0)
(push $3)
(call &pln)
(call &pln ($3) nil)
(halt))
(label pln
(load-immediate $0 &terminal-namespace) ; get terminal device
(load-immediate $1 &terminal-namespace) ; get terminal device
(load-immediate $11 0)
(syscall OPEN $0 $0 $11)
(syscall OPEN $1 $1 $11)
(load-immediate $3 &new-line)
(pop $1)
(load-offset-32 $7 $0 4) ; load handle
(string-length $2 $1)
(syscall WRITE $7 $1 $2)
(load-offset-32 $7 $1 4) ; load handle
(string-length $2 $0)
(syscall WRITE $7 $0 $2)
(string-length $4 $3)
(syscall WRITE $7 $3 $4)
(return)))
(return nil)))
(data
(label terminal-namespace "/dev/term/0")
(label help "Enter a string: ")

View File

@ -5,29 +5,23 @@
(syscall OPEN $0 $0 $11)
(load-immediate $1 &help) ; print help message
(push $0)
(push $1)
(call &pln)
(call &pln ($0 $1) nil)
(load-immediate $1 32) ; read in a string of max 32 char length
(malloc $4 $1) ; allocate memory for the string
(load-offset-32 $7 $0 4) ; load handle
(syscall READ $7 $2 $1 $4) ; read the string
(push $0)
(push $4)
(call &pln) ; print the string
(call &pln ($0 $4) nil) ; print the string
(halt))
(label pln
(load-immediate $3 &new-line)
(pop $1)
(pop $0)
(load-offset-32 $7 $0 4) ; load handle
(string-length $2 $1)
(syscall WRITE $7 $1 $2)
(string-length $4 $3)
(syscall WRITE $7 $3 $4)
(return)))
(return nil)))
(data
(label terminal-namespace "/dev/term/0")
(label help "Enter a string: ")

13
test/malloc.ul Normal file
View File

@ -0,0 +1,13 @@
str terminal_namespace = "";
str prompt = "Enter a string: ";
function main() {
Terminal term(terminal_namespace, 0);
pln(prompt);
pln(terminal.read(32));
return 0;
}
function pln(ref Terminal term, str message) {
term.write(message);
}

Binary file not shown.

View File

@ -4,7 +4,7 @@
; use load immediate because it is a pointer to a string, not a value
(load-immediate $0 &screen-namespace)
(load-immediate $11 0)
(syscall OPEN $18 $0 $11) ; open(out Plex screen, in namespace, in flags)
(syscall OPEN $18 $0 $11) ; Screen screen = open(namespace, flags)
(load-offset-32 $0 $18 4) ; load handle
(load-offset-32 $20 $18 8) ; load width
@ -14,31 +14,21 @@
; open mouse
(load-immediate $16 &mouse-namespace)
(syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags)
(syscall OPEN $15 $16 $11) ; Mouse mouse = open(namespace, flags)
(load-offset-32 $16 $15 4) ; load handle
; outline_swatch(screen, BLACK, 1, 1);
(push $21)
(push $20)
; outline_swatch(screen, BLACK, 1, 1, width);
(load-absolute-32 $1 &BLACK)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 1)
(push $13)
(call &draw-outlined-swatch)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; outline_swatch(screen, WHITE, 1, 1);
(push $21)
(push $20)
; outline_swatch(screen, WHITE, 1, 1, width);
(load-absolute-32 $1 &WHITE)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 1)
(push $13)
(call &draw-outlined-swatch)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; screen.draw();
(syscall WRITE $0 $21 $22)
@ -57,60 +47,31 @@
(load-immediate $14 20) ; box size
; first row
(push $21)
(push $20)
(load-absolute-32 $1 &BLACK)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 1)
(push $13)
(call &draw-outlined-swatch)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
(push $21)
(push $20)
(load-absolute-32 $1 &WHITE)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 1)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
; row 2
(push $21)
(push $20)
(load-absolute-32 $1 &CHARCOAL)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 21)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
(push $21)
(push $20)
@ -120,15 +81,10 @@
(push $12)
(load-immediate $13 21)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
; row 3
(push $21)
@ -139,107 +95,54 @@
(push $12)
(load-immediate $13 41)
(push $13)
(call &draw-outlined-swatch)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
(push $21)
(push $20)
(load-absolute-32 $1 &ORANGE)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 41)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
; row 3
(push $21)
(push $20)
(load-absolute-32 $1 &YELLOW)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 61)
(push $13)
(call &draw-outlined-swatch)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
(push $21)
(push $20)
(load-absolute-32 $1 &GREEN)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 61)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
; row 4
(push $21)
(push $20)
(load-absolute-32 $1 &BLUE)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 81)
(push $13)
(call &draw-outlined-swatch)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
(push $21)
(push $20)
(load-absolute-32 $1 &PURPLE)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 81)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(call &set-color-if-clicked)
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
; set_color_if_clicked(color, click_x, click_y, box_x, box_y, 20);
(call &set-color-if-clicked ($1 $7 $8 $12 $13 $14) nil)
(syscall WRITE $0 $21 $22)
@ -253,7 +156,8 @@
(push $8) ;y
(push $1)
(push $1)
(call &draw-box)
; draw_box(brush_size, )
(call &draw-box ($1 $1 $8 $7 $22 $20 $21) nil)
(jump &draw-loop))

246
docs/paint.ul → test/paint.ul Executable file → Normal file
View File

@ -1,119 +1,127 @@
/**
* Constatnts
*/
const str screen_namespace = "/dev/screen/0";
const str mouse_namespace = "/dev/mouse/0";
const byte BLACK = 0;
const byte WHITE = 255;
const byte DARK_GRAY = 73;
const byte GRAY = 146;
const byte LIGHT_GRAY = 182;
byte selected_color = 255;
interface Device {
nat handle;
}
plex Screen implements Device {
nat handle;
nat width;
nat height;
nat buffer_size;
byte[] screen_buffer;
init(str namespace) {
this.handle = open(namespace);
}
}
plex Mouse implements Device {
u32 handle;
u32 x;
u32 y;
u8 btn1;
u8 btn2;
u8 btn3;
u8 btn4;
u32 size;
}
/**
* Main function
*/
function main() {
Screen screen(screen_namespace);
screen.open(0);
Mouse mouse(mouse_namespace);
mouse.open(0);
outline_swatch(screen, BLACK, 1, 1);
outline_swatch(screen, WHITE, 21, 1);
screen.draw();
loop {
mouse.read();
if (not mouse.left) continue;
int box_size = 20;
int x = 1;
int y = 1;
byte color = BLACK;
outlined_swatch(screen, color, x, y);
set_color(box_size, x, y, mouse.x, mouse.y, color);
color = WHITE;
x = 21;
outlined_swatch(screen, color, x, y);
set_color(box_size, x, y, mouse.x, mouse.y, color);
screen.draw();
rectangle(screen, selected_color, x, y, 5, 5);
}
exit(0);
}
/**
* Checks if the click is within the bound and update the selected color if so.
*/
function set_color(int box_size, int bx, int by, int mx, int my, byte color) {
int right = bx + box_size;
int bottom = by + box_size;
if (mx < bx) return;
if (mx > right) return;
if (my < by) return;
if (my > bottom) return;
selected_color = color;
return;
}
/**
* Draw a color box with a grey outline, if selected use a darker color
*/
function outline_swatch(ref Device screen, byte color, int x, int y) {
byte bg_color = GRAY;
if (selected_color == color) {
bg_color = DARK_GRAY;
}
rectangle(screen, bg_color, x, y, 20, 20);
rectangle(screen, color, x + 2, y + 2, 17, 17);
return;
}
/**
* Draw a rectanlge
*/
function rectangle(ref Device screen, byte color, int x, int y, int width, int height) {
int pixel = y * width + x + screen.buffer.ptr + 4;
do (int i = height; i > 0; i--) {
int row = pixel + width;
screen.set(row, color, width);
pixel += width;
}
return;
}
/**
* Constants
*/
const str screen_namespace = "/dev/screen/0";
const str mouse_namespace = "/dev/mouse/0";
const byte BLACK = 0;
const byte WHITE = 255;
const byte DARK_GRAY = 73;
const byte GRAY = 146;
const byte LIGHT_GRAY = 182;
byte selected_color = 255;
interface Device {
nat handle;
}
plex Screen implements Device {
nat handle;
nat width;
nat height;
nat buffer_size;
byte[] screen_buffer;
init(str namespace) {
this.handle = open(namespace);
}
}
plex Mouse implements Device {
nat handle;
nat x;
nat y;
bool left;
bool right;
bool middle;
bool btn4;
nat size;
init(str namespace) {
this.handle = open(namespace);
}
}
/**
* Main function
*/
function main() {
Screen screen(screen_namespace);
screen.open(0);
Mouse mouse(mouse_namespace);
mouse.open(0);
outline_swatch(screen, BLACK, 1, 1);
outline_swatch(screen, WHITE, 21, 1);
screen.draw();
loop {
mouse.read();
if (not mouse.left) continue;
int box_size = 20;
int x = 1;
int y = 1;
byte color = BLACK;
outlined_swatch(screen, color, x, y);
set_color(box_size, x, y, mouse.x, mouse.y, color);
color = WHITE;
x = 21;
outlined_swatch(screen, color, x, y);
set_color(box_size, x, y, mouse.x, mouse.y, color);
screen.draw();
rectangle(screen, selected_color, x, y, 5, 5);
}
exit(0);
}
/**
* Checks if the click is within the bound and update the selected color if so.
*/
function set_color(int box_size, int bx, int by, int mx, int my, byte color) {
int right = bx + box_size;
int bottom = by + box_size;
if (mx < bx) return;
if (mx > right) return;
if (my < by) return;
if (my > bottom) return;
selected_color = color;
return;
}
/**
* Draw a color box with a grey outline, if selected use a darker color
*/
function outline_swatch(ref Device screen, byte color, int x, int y) {
byte bg_color = GRAY;
if (selected_color == color) {
bg_color = DARK_GRAY;
}
rectangle(screen, bg_color, x, y, 20, 20);
rectangle(screen, color, x + 2, y + 2, 17, 17);
return;
}
/**
* Draw a rectangle
*/
function rectangle(ref Device screen, byte color, int x, int y, int width, int height) {
// we need unsafe because we are using `ptr` and `memset` directly
// unsafe takes the guardrails off and allows you to access/modify memory directly
unsafe {
int pixel = y * width + x + screen.buffer.ptr + 4;
do (int i = height; i > 0; i--) {
int row = pixel + width;
memset(screen.buffer.ptr, row, color, width);
pixel += width;
}
}
return;
}

View File

@ -4,21 +4,19 @@
(load-absolute-32 $1 &y)
(add-real $2 $1 $0)
(real-to-string $3 $2)
(push $3)
(call &pln)
(call &pln ($3) nil)
(halt))
(label pln
(load-immediate $0 &terminal-namespace) ; get terminal device
(load-immediate $1 &terminal-namespace) ; get terminal device
(load-immediate $11 0)
(syscall OPEN $0 $0 $11)
(syscall OPEN $1 $1 $11)
(load-immediate $3 &new-line)
(pop $1)
(load-offset-32 $7 $0 4) ; load handle
(string-length $2 $1)
(syscall WRITE $7 $1 $2)
(load-offset-32 $7 $1 4) ; load handle
(string-length $2 $0)
(syscall WRITE $7 $0 $2)
(string-length $4 $3)
(syscall WRITE $7 $3 $4)
(return)))
(return nil)))
(data (label terminal-namespace "/dev/term/0")
(label new-line "\n")
(label x 1.0)

View File

@ -1,10 +1,5 @@
((code
(label main
; open terminal for debug
(load-immediate $32 &terminal-namespace)
(load-immediate $11 0)
(syscall OPEN $32 $32 $11)
; Open screen
; use load immediate because it is a pointer to a string, not a value
(load-immediate $0 &screen-namespace)
@ -13,31 +8,23 @@
(load-offset-32 $0 $18 4) ; load handle
(nat-to-string $5 $0)
(push $32)
(push $5)
(call &pln)
(call &pln ($5) nil)
(load-offset-32 $20 $18 8) ; load width
(nat-to-string $5 $20)
(push $32)
(push $5)
(call &pln)
(call &pln ($5) nil)
(load-offset-32 $22 $18 12) ; load size
(nat-to-string $5 $22)
(push $32)
(push $5)
(call &pln)
(call &pln ($5) nil)
(load-immediate $1 16) ; offset for screen buffer
(add-nat $21 $18 $1)
(nat-to-string $5 $21)
(push $32)
(push $5)
(call &pln)
(call &pln ($5) nil)
; open mouse
(load-immediate $16 &mouse-namespace)
@ -72,18 +59,17 @@
(jump &draw-loop))
(halt))
(label pln
(load-immediate $3 &new-line)
(pop $1)
(pop $0)
(load-offset-32 $7 $0 4) ; load handle
(string-length $2 $1)
(syscall WRITE $7 $1 $2)
(string-length $4 $3)
(syscall WRITE $7 $3 $4)
(return)))
(label pln
(load-immediate $1 &terminal-namespace) ; get terminal device
(load-immediate $11 0)
(syscall OPEN $1 $1 $11)
(load-immediate $3 &new-line)
(load-offset-32 $7 $1 4) ; load handle
(string-length $2 $0)
(syscall WRITE $7 $0 $2)
(string-length $4 $3)
(syscall WRITE $7 $3 $4)
(return nil)))
(data
(label screen-namespace "/dev/screen/0")
(label mouse-namespace "/dev/mouse/0")