<geri>
that's what im using, is anything wrong with it?
<abu[7]>
No, but 'N avoids unnecessary building the string
<geri>
well i need the path, so its necessary
<abu[7]>
The path is returned as a list in 'R'
<abu[7]>
from the automatic buffer created by native
<abu[7]>
If you want to use 'S, you can pass null for the buffer
<abu[7]>
but then you must keep the pointer
<abu[7]>
and free() it
<abu[7]>
i.e. use 'P or 'N
<abu[7]>
convert to string using 'struct`
<abu[7]>
then free the pointer
<abu[7]>
tedious :)
<geri>
do i have a memory leak rn?
<abu[7]>
Not if you use (R (`PATH_MAX C . `PATH_MAX))
<abu[7]>
Then native allocates *and* deallocabnes
<abu[7]>
deallocates
<geri>
scroll a bit up, i have 'S for return result and 'R for everything else
<abu[7]>
Yes, I said it is fine
<geri>
ok xd
<geri>
im just confused at this point :D
<abu[7]>
Just passing null would be easier but leak :)
<abu[7]>
Sorry :)
<geri>
hm
<geri>
i mean, if i didnt pass anything it just crashed
<abu[7]>
Crashing is easy :)
<abu[7]>
btw, you don't need R then
<abu[7]>
(NIL (`PATH_MAX C . `PATH_MAX))
<geri>
to crash?
<abu[7]>
so you can omit (use R ...)
<abu[7]>
No, crashing is independent of that
<abu[7]>
Just if you pass a variable R
<abu[7]>
you need to bind it
<abu[7]>
(use R ... (%@ ... '(R ...
<abu[7]>
Because it is 'set' by the native call
<geri>
(native "@" "realpath" 'S "/home/geri/.bashrc" (cons PATH_MAX C PATH_MAX))
<geri>
something like that?
<geri>
(i dont understand why cons works with 3 values
<geri>
)
<abu[7]>
(%@ "realpath" 'S filePath '((`PATH_MAX C . `PATH_MAX)))
<abu[7]>
oops
<abu[7]>
(%@ "realpath" 'S filePath '(NIL (`PATH_MAX C . `PATH_MAX)))
<abu[7]>
Just replaced R with NIL
<abu[7]>
To avoid (use R
<abu[7]>
(I suspect you did not call 'use' or 'let' for 'R')
<geri>
yeah thats the whole function
<abu[7]>
So sorry, I did not want to confuse but just be correct
<abu[7]>
A correct usage of storing in R needs binding R
<abu[7]>
It works without, but may cause unexpected errors
<abu[7]>
i.e. if some caller happens to use 'R' too
<abu[7]>
It might get it overwritten
<geri>
i dont really understand half of that readpath command xd
<geri>
%@ is an alias for native "@", i.e. use librar(y/ies) current pil uses
<geri>
'S is the return type
<geri>
filepath is self-explanatory
<abu[7]>
Yeah, it is a typical C mess function
<geri>
other stuff i dont understand
<geri>
ik it should take a buffer and a buffer size but like what's going on at pico's side idk
<abu[7]>
yes, a bit magic
<geri>
most other native calls were easy at least
<abu[7]>
Pil allocates a buffer, stores the result returned from C in 'R', and frees the buffer
<geri>
/magic/ basically
<geri>
:D
<abu[7]>
Perhaps this is easier?
<abu[7]>
(buf P 4096 (%@ "realpath" 'S "lib.l" P))
<abu[7]>
i.e. we explicitly allocate a buffer on he stack
<abu[7]>
in P
<geri>
oh we can allocate stuff too?
<geri>
amazing
<abu[7]>
'buf' came with pil21
<abu[7]>
Many complicated constructs for 'native' may be not needed any mobe
<abu[7]>
more
<geri>
oh hey, pico's still going smaller? :D
<abu[7]>
Always :)
<geri>
sweet minimalism
<geri>
time to try to write some more stuff
<abu[7]>
Good
<geri>
how is pico so fast while being interpreted anyway?
<abu[7]>
It kind of "executes" the cell structures directly
<geri>
how does it happen in cl/schemes in contrast?
<abu[7]>
They are orientet towards compilation
<abu[7]>
So they need static binding, which is fast when compiled but slow to interprete
<geri>
ah, so embracing the interpretation lets you do that
<abu[7]>
In addition, Pil lets each function evaluabne its args by itself
<abu[7]>
yes
<geri>
neat!
<abu[7]>
Compiled code evaluates all args, then calls the function
<abu[7]>
Thats a lot less efficient and has more overhead
<geri>
oh yeah, i remember about conditional evaluation
<abu[7]>
Pil just jumps from built-in to built-n using the cell pointers
bjorkint0sh has joined #picolisp
<geri>
it kinda does half of what macros do too
<abu[7]>
This is another issuue
<geri>
at least most of my macros are like "please dont evaluate this"
<abu[7]>
yes, macros are good for compiled code
<abu[7]>
Pil uses FEXPs
<abu[7]>
and all built-ins are FSUBRs
<abu[7]>
so each fun decides what to do with the args
<abu[7]>
very flexible
<geri>
yeah
<abu[7]>
and fast, as no "special" funs exist
<abu[7]>
cond, setq etc.
<geri>
so pretty much everything is up for edits?
<abu[7]>
In which way?
<geri>
like if nothing is special you can redifine almost everything
<geri>
or something
<abu[7]>
Right
<geri>
nice
<geri>
btw, where'd `de` come from?
<abu[7]>
I think it is from Interlisp
<abu[7]>
The main reason is shortness
<abu[7]>
A predecessor of Pil was 8kLisp
<abu[7]>
In 8 KiB
<abu[7]>
so every byte was precious
<geri>
ah
<geri>
like ed!
<abu[7]>
T
<abu[7]>
sorry, bbl
<geri>
but wait, if space was precious, why add space when paren ends on a different line? 🤔
<geri>
guessing its easier to see where stuff ends then
<geri>
also raydeejay sends their regards :D
<abu[7]>
White space in source files does not matter, they are just I/O. But a symbol name like "de" is kept permanently in memory
<abu[7]>
Regards to Raydeejay too ;)
<geri>
dont extra spaces *technically* increase amount of io you gotta do, making it slower? :D
<abu[7]>
That's true, a little
<abu[7]>
but skipping white space is fast
<geri>
was it fast back then too?
<abu[7]>
Relatively, but of course a lot slower due to the hardware
<abu[7]>
: (bench (fibo 23))
<abu[7]>
0.003 sec
<abu[7]>
I think it was six minutes on 8kLisp
<geri>
that's like 10 times faster than my bootstrapping script
<abu[7]>
on CP/M 80
<geri>
how *time flies*
<abu[7]>
Yeah
<geri>
also i imagined you going like "oh we need to support shebang? lets make all comments start with shebang, hell with those lisp traditions" and its very funny
<geri>
thats current shebang for the bootstrap script
<abu[7]>
uh
<abu[7]>
;)
<geri>
:; is my bash prompt!
<geri>
polyglot scripts are cool but an unobstructed shebang is nice to have
<abu[7]>
yep
<geri>
why does (setq a 'b) (print '(+ `a)) work but (let (a 'b) (print '(+ `a))) - no?
<geri>
ive tried (let a 'b ...) too
<abu[7]>
`a is a read-macro. It is evaluated at read time, not eval time
<geri>
how do i unquote properly then?
<abu[7]>
You mean the backquote in CL?
<abu[7]>
I would not call this unquote, it is a replacement
<geri>
yeah, like `(a b ,c) in cl
<abu[7]>
'fill' is similar
<abu[7]>
but different syntax
<abu[7]>
and more variations
<abu[7]>
(let @X 7 (fill '(a b @X c)))
<abu[7]>
(let X 7 (fill '(a b X c) 'X))
<abu[7]>
and ^ splices whole sublists
<abu[7]>
So a read-macro is something different
<abu[7]>
The backquote is a nice short syntay
<abu[7]>
syntax
<geri>
oh great, worked
<abu[7]>
Why waste such a precious char on a function
<geri>
what does backquote do exactly?
<abu[7]>
(the backquote in CL is in fact a function like 'fill)
<geri>
yeah
<abu[7]>
When the reader sees ` or ~, it reads the next expression, and uses the *result* in the expression being currently read
<abu[7]>
Very similar to #define macros in C perhaps
<abu[7]>
Well, just kind of :)
<geri>
i think i need an example in this one
<abu[7]>
(de f () (+ 2 `(* 3 4)))
<abu[7]>
(pp 'f)
<abu[7]>
gives (+ 2 12)
<geri>
cause when i hear "read macros" im thinking something like 'thing gets read as (quote thing)
<abu[7]>
Not so wrong
<geri>
is it like for optimizations?
<geri>
evaluate this once and never again
<abu[7]>
Yes, optim, but also avoids re-evaluation
<geri>
well, eval once, insert into whatever youve been reading and never waste cpu cycles on it again
<abu[7]>
Right
<geri>
very cool
<abu[7]>
But consider `*Dbg in some sources
<abu[7]>
This is a trick :)
<geri>
is backquote behaviour also written in pico?
<abu[7]>
When 'loading' a file, reading NIL is considered as EOF
<abu[7]>
so the file is not further loaded
<abu[7]>
The backquote behaviour is in the base system
<abu[7]>
in the reader
<abu[7]>
(vi 'llvm~read0)
<abu[7]>
((== C (char "`"))
<abu[7]>
this line and following
<geri>
vi command doesnt work for that one, probably related to nix being itself
<abu[7]>
So not written in PicoLisp but in PilSrc
<geri>
do you remember where it is in the git tree?
<abu[7]>
Ii is in @src/io.l
<abu[7]>
Line 1561
<abu[7]>
(currert version)
<geri>
ah okay
<geri>
i thought base would be in like C so the src folder made no sense for me
<geri>
cause i know nothing about llvm
<abu[7]>
PilSrc looks like Pil, but isn't
<abu[7]>
It compiles to llvm
<abu[7]>
Well, in fact it *is* Pil, but many functions redefined
<geri>
and where is pilsrc defined? :D
<abu[7]>
In @src/lib/llvm.l
<geri>
its defined in itself? ~w~
<abu[7]>
It creates functions in the 'llvm' namespace
<abu[7]>
yes
<abu[7]>
e.g. 'de' starts writing llvm code to the output file
<geri>
snakes eating their tails, yum
<abu[7]>
yes :)
<geri>
is it like you wrote it once in C, now its migrated to llvm and you can't recover without another version of pico or is there some magical bootstrapping process?
<geri>
(not necessarily in C)
<abu[7]>
Right, first was C
<abu[7]>
Whe pre-compiled src/base.ll is in the distro
<abu[7]>
so LLVM can build the interpreter
<abu[7]>
After that it re-builds stand-alone
<geri>
ah, so base.ll is the kernel fromwhich you can do everything else
<geri>
base.lispyLisp
<abu[7]>
It is the whole interpreter
<abu[7]>
The biggest file in the distro
<geri>
it looks kinda scary in this form
<abu[7]>
Indeed! Ugly.
<geri>
110896 lines
<geri>
im glad nobody has to rewrite that from scratch
<abu[7]>
T
<geri>
self hosted interpreters/compilers are honestly scary if you're the only developer
<abu[7]>
But both pil and llvm are simple enough to do it relatively easily
<abu[7]>
A full C compiler is a *lot* more stuff
<geri>
write the initial interpreter to interpret your interpreter interpreting code?
<geri>
:D
<abu[7]>
Kind of, yes :)
<geri>
i wrote a very basic lisp parser like 2 days ago, honestly it was kinda hard
<geri>
and i did it abusing cl's stream functionality, so no peek or next
<geri>
...need to be written*
<abu[7]>
ok
<geri>
i cant image how people managed to write lisps in asm
<abu[7]>
Takes time, but may be fun :)
<geri>
yeah
<geri>
i wrote a really bad scheme interpreter in cl too, was super fun
<abu[7]>
:)
<geri>
i use dynamic variables to implement lexical ones
<geri>
xd
<geri>
cause i couldnt figure out how else to make `define' actually work
<abu[7]>
Not sure about Scheme, but there are many ways it seems
<geri>
yeah, way too many to count
<abu[7]>
moment, brb
abu[7] has left #picolisp [#picolisp]
abu[7] has joined #picolisp
<geri>
wb
<geri>
i actually gotta go myself
<geri>
enjoy your (dat$) # misused!
<abu[7]>
Have a good time!
geri has quit [Quit: ERC 5.5.0.29.1 (IRC client for GNU Emacs 29.3)]
pablo_escoberg has joined #picolisp
<pablo_escoberg>
Hey, has anybody played with this: https://github.com/vygr/ChrysaLisp ? Seems like a hell of a project and I just heard about it on HN.
<abu[7]>
Never saw it
<pablo_escoberg>
me too. But it's quite developed. Seems like what pilOS could be, almost...
<pablo_escoberg>
which actually reminds me of a question I've had for a while: would it be possible to build some kind of shim that would allow pilOS to use Linux drivers?
<beneroth>
I don't know about the pilOS Linux driver question - but I suspect that would require a very large shim. I guess Linux drivers are based on the Linux Kernel ABI. Also somewhat the point of pilOS was to leave all that bloat away.