Retrogamecoding(.org) > Announcements
PulsarBASIC - Teaser thread
Aurel:
well yes
but must be there some C example about that ?
Cybermonkey:
I didn't find one, yet. So if anyone has an example, feel free to post it here. ;)
Aurel:
I found it long time ago somewhere but i don't know now ...
Ed Davis:
--- Quote from: Cybermonkey on June 11, 2019, 07:15:59 AM ---I didn't find one, yet. So if anyone has an example, feel free to post it here. ;)
--- End quote ---
--- Quote from: Cybermonkey on June 11, 2019, 07:15:59 AM ---I didn't find one, yet. So if anyone has an example, feel free to post it here. ;)
--- End quote ---
How about this?
First, the binder - to compile: gcc -s -Os -o binder binder.c
--- Code: ---/*
--binder=> bind runtime script output-filename -----------
To build: gcc -s -Os -o binder.exe binder.c
ed_davis2@yahoo.com
arg[1] = runtime
arg[2] = script
arg[3] = output-filename
copy_file(arg[1], arg[3]) -- copy runtime to output
copy_file(arg[2], arg[3], APPEND) -- append script to output
--append runtime length
write(arg[3], format(filesize(arg[1]):8:'0'), APPEND)
-- append script length
write(arg[3], format(filesize(arg[2]):8:'0'), APPEND)
-- append a pity eyecatcher
write(arg[3], format("Southern":8:'0'), APPEND)
halt
--interpreter---------------------------------------------------
-- find the size of the runtime
f = open(arg[0], "r")
seek(f, -24, SEEK_END)
new string buf(8)
read(f, buf, buf.size)
runtime_size = val(buf)
read(f, buf, buf.size)
script_size = val(buf)
read(f, buf, buf.size)
if buf <> "Southern" error("Eyecatcher not found!!!")
-- read in the script
seek(f, runtime_size, SEEK_SET)
new string buf(script_size)
read(f, buf, script_size)
close(f)
run(buf)
halt
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#if defined(__linux__)
#include <unistd.h>
#include <sys/stat.h>
#define stricmp strcasecmp
#endif
enum {n_interp = 1, n_script = 2, n_final = 3, REPLY_SIZE = 4};
int main(int argc, char *argv[]) {
FILE *interp, *script, *final;
int c, rt_size, script_size;
if (argc < 4) {
printf("format: binder interp script output-file\n");
return 2;
}
interp = fopen(argv[n_interp], "rb");
if (!interp) {
perror(argv[n_interp]);
return 2;
}
script = fopen(argv[n_script], "rb");
if (!script) {
perror(argv[n_script]);
return 2;
}
/* don't overwrite output without confirmation */
final = fopen(argv[n_final], "rb");
if (final) {
char buf[REPLY_SIZE];
fclose(final);
printf("File %s exists - delete it? (y/n)\n", argv[n_final]);
if (!fgets(buf, REPLY_SIZE, stdin)) {
printf("Nothing ventured, nothing gained\n");
return 2;
}
if (buf[0] != 'y') {
printf("Please try again later\n");
return 2;
}
}
final = fopen(argv[n_final], "wb");
if (!final) {
perror(argv[n_final]);
return 2;
}
rt_size = 0;
while ((c = fgetc(interp)) != EOF) {
fputc(c, final);
++rt_size;
}
fclose(interp);
printf("Interp size is %d\n", rt_size);
script_size = 0;
while ((c = fgetc(script)) != EOF) {
fputc(c, final);
++script_size;
}
fclose(script);
printf("Script size is %d\n", script_size);
fprintf(final, "%08d", rt_size);
fprintf(final, "%08d", script_size);
fprintf(final, "31415926");
fclose(final);
printf("%s size is %d + %d + %d = %d\n", argv[n_final],
rt_size, script_size, 24, rt_size+script_size+24);
#if defined(__linux__)
chmod(argv[n_final], 0755);
#endif
printf("%s bound to %s in %s\n", argv[n_script], argv[n_interp], argv[n_final]);
return 0;
}
--- End code ---
Then the interpreter - to compile: gcc -s -Os -o pl0 pl0.c
Just showing the "load the code routine here". Complete interpreter is attached as pl0.c.
--- Code: ---/*------------------------------------------------------------------------
-- find the size of the runtime
f = open(arg[0], "r")
seek(f, -24, SEEK_END)
new string buf(8)
read(f, buf, buf.size)
runtime_size = val(buf)
read(f, buf, buf.size)
script_size = val(buf)
read(f, buf, buf.size)
if buf <> "Southern" error("Eyecatcher not found!!!")
-- read in the script
seek(f, runtime_size, SEEK_SET)
new string buf(script_size)
read(f, buf, script_size)
close(f)
data is stored in 3 8 char fields:
0..7: size of the exe
8..15: size of the appended script
16..23: eyecatcher
------------------------------------------------------------------------*/
int load_script(void) {
FILE *fp;
char buf[24], buf2[9];
int size_read, rt_size;
char exe_name[PATH_MAX];
/* get the exec name */
#if defined(__WIN32)
GetModuleFileName(NULL, exe_name, MAX_PATH);
#elif defined(__linux__)
char linkname[PATH_MAX];
struct stat finfo;
int len;
sprintf(linkname, "/proc/%d/exe", getpid());
if ((len = readlink(linkname, exe_name, PATH_MAX - 1)) > 0) {
exe_name[len] = '\0';
} else {
perror("Error: ");
return false;
}
#endif
fp = fopen(exe_name, "rb");
if (!fp) {
perror(exe_name);
return false;
}
/* 24 bytes from end, to read 3 fields noted above */
if (fseek(fp, -24, SEEK_END) != 0) {
perror("fseek: ");
return false;
}
/* read all 3 fields */
size_read = fread(buf, 1, sizeof(buf), fp);
/* eyecather matches? (3rd field) */
if (memcmp(&buf[16], "31415926", 8) != 0) {
printf("Eyecatcher not found\n");
return false;
}
/* first field, the exe length */
memcpy(buf2, buf, 8);
buf2[8] = '\0';
rt_size = strtol(buf2, NULL, 10);
/* second field, the script length */
memcpy(buf2, &buf[8], 8);
buf2[8] = '\0';
script_size = strtol(buf2, NULL, 10);
script = malloc(script_size);
/* seek to the start of the script */
if (fseek(fp, rt_size, SEEK_SET) != 0) {
perror("fseek: ");
return false;
}
size_read = fread(script, 1, script_size, fp);
fclose(fp);
if (size_read != script_size) {
printf("Could not read entire script: asked %d got %d\n", script_size, size_read);
return false;
}
return true;
}
--- End code ---
And a simple script to be bound:
--- Code: ---const left = 0, middle = 1, right = 2;
procedure move(n, source, aux, dest);
procedure printmove();
procedure printpole(p);
begin
if p = 0 then
write('left ');
elseif p = 1 then
write('middle');
elseif p = 2 then
write('right ');
end;
end;
begin {printmove}
write('Move a disk from '); printpole(source);
write(' to '); printpole(dest);
writeln();
end;
begin {move}
if n = 1 then
printmove();
else
move(n-1, source, dest, aux);
printmove();
move(n-1, aux, source, dest);
end;
end;
var disks;
begin
repeat
writeln();
write('Number of disks (2-10, 1 to stop)? ');
read(disks);
if (disks > 1) and (disks <= 10) then
writeln();
writeln('For ', disks, ' disks, the required moves are:');
writeln();
move(disks, left, middle, right);
end;
until disks = 1;
end.
--- End code ---
To bind:
binder pl0 hanoi.pl0 hhh
(binder pl0.exe hanoi.pl0 hhh.exe on Windows)
Tested under Windows and Linux.
Let me know if you have questions/problems.
Cybermonkey:
Ok, thanks that's what I was looking for. So far as I can see, one can't start a script simply by writing
--- Code: ---pl0 hanoi.pl0
--- End code ---
Error is
--- Quote ---Eyecatcher not found
--- End quote ---
Would of course be nice that one could use the interpreter in both ways... well, I will have a closer look on the weekend.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version