Log In  


Cart #picoforth-4 | 2021-06-04 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
12


Welp, this took way to long to finish. But now it's here!

about

picoforth is a programming language based on Forth, a family of stack-based programming languages. If you're unfamiliar with stack-based programming languages or Forth, I recommend you check out this site.

wordlist

Here is a list of every word in picoforth. (A "word" in a stack-based language is roughly equivalent to a "function" or a "subroutine" in a normal programming language.)

--typical forth stack-manipulating words
pop
2pop
dup
2dup
over
swap
rotl
rotr

--mathematical operators
+
-
*
/
// --integer division
^

--comparing operators
=
~=
>
<

--bitwise operators
& --bitwise and, or, shr, shl, xor, and not, respectively
|
>>
<<
^^
~

--storing and recalling
! --peek and poke, respectively
@

--printing
. --prints the popped item (works with strings and numbers)
.stack --prints the entire stack (doesn't affect anything)

--key operations
chr
ord
key --halts the program until a key is pressed; pushes the pressed key
input --repeats key until enter is pressed; pushes the finished string

--branching
branch --relative branch: I(nstruction)P(ointer) becomes the sum of itself and popped item
goto --absolute branch: sets the IP to popped item

--screen drawing
cls
flip
spr
pset

--strings
" -- opens a string, then closes it the next time it's used (i.e.  " asdf " .  will print asdf)
"" --pushes an empty string
join --concatenates the two top popped items
sub
# --length of string

--miscellaneous
exec --runs the popped item as if it were forth code
time --pushes t()\1
rnd  --pushes rnd(poppeditem\1)
sin  --pushes sin(poppeditem)
cos  --pushes cos(poppeditem)
def  --pushes the definition of popped item
interpret --repeats input + exec forever

--creating new words
: -- : name-of-new-word [definition] ;
;

Here's an example program, the one that generated the label image:

0 1 + dup dup 0x6000 + dup rotl ! 0x7fff < 2 * goto

Post any spinoffs of this cart/programs in picoforth that you made in the comments. I'd love to see them!
For the previous picoforth, which was a work-in-progress, see this cart.

12


1

this seems cool! :)


Thanks!


1

Wow, that is incredible! It's genuinely awesome to see people implement programming languages in this little FC. Forth especially, I've made a language inspired by it before. Here is the link to the entry on the Esolang wiki.
Download
Documentation


how does spr work here?


1

I'm totally into this. Nice work!


1

@Pico_Maker
Short answer:

[spritenumber] [x] [y] spr

Long answer:


Using [value] [address] ! (poke) you can poke the sprite-sheet memory (https://pico-8.fandom.com/wiki/Memory#Sprite_sheet), then you can display it using spr. As an example,

-1 1 + dup 0x6000 ! 0 1 + over over swap 4 * + " @▮••▮れC▮0▤▤□…▥▤「…▤そ「…そ▤「0▤▤□▮★8▮ " swap dup sub ord 16 - over 0x6000 @ 64 * 1 - + ! dup 4 ~= -32 * branch pop dup 7 ~= -45 * branch pop cls 0 64 64 spr

The string @▮••▮れC▮0▤▤□…▥▤「…▤そ「…そ▤「0▤▤□▮★8▮ is the sprite data in bytes, with each value shifted up by 16 (because the first 16 characters are control characters/whitespace and do not work correctly/at all in strings) and converted to characters to save space. The example program above goes though each character in the string (using sub), converts it to a number (using ord), subtracts 16 from it, then calculates the correct address and pokes, repeating until it's finished.

When you copy a sprite in pico-8, it uses this format. Here's a tool to convert a copied sprite to a string like the one used in the example program:

Cart #sprite_to_string-2 | 2021-12-30 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
1




1

Came back a lot later, still great, one problem though: there isn't a for loop. I'll look into it further later, for now I have other stuff to do.


1

@Pico_Maker
There is no need for a for loop— that's what branch and goto are for. As an example:

0x5FFF 1 + dup 8 swap ! dup 0x603F ~= 2 * goto

Which is roughly equivalent to the following pico-8 code:

a = 0x5FFF
::_:: a+=1
poke(a, 8)
if(a ~= 0x603F)goto _

or more succinctly,

for i=0x5FFF,0x603F do
 poke(i,8)
end

@Einstein2
Ok, thanks!

Edit: So, is this right(?):
<from> <step> + <put code here> dup <to> ~= 2 * goto

Edit0: Yes, it is.


1


[Please log in to post a comment]