Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BASIC does not report error location #2199

Closed
toncho11 opened this issue Jan 22, 2025 · 18 comments
Closed

BASIC does not report error location #2199

toncho11 opened this issue Jan 22, 2025 · 18 comments

Comments

@toncho11
Copy link
Contributor

toncho11 commented Jan 22, 2025

Is it possible that we add at which line (text file line) the error occurred?

@ghaerr
Copy link
Owner

ghaerr commented Jan 22, 2025

Basic does report the line number for which the error occurred, as long as there is a line number - see host.c::loop():

    if (ret != ERROR_NONE) {
        host_newLine();
        if (lineNumber != 0) {
            host_outputLong(lineNumber);
            host_outputChar('-');
        }
        printf("%s\n\n", errorTable[ret]);

It says two times "Unexpected input", but it does not say where.

The error you are receiving, "Unexpected Input" is returned in basic.c in only two places, in the function nextToken (ERROR_LEXER_UNEXPECTED_INPUT). The first case is:

        // no matching keyword - this must be an identifier
        // $ is only allowed at the end
        char *dollarPos = strchr(identStr, '$');
        if  (dollarPos && dollarPos!= &identStr[0] + identLen - 1) return ERROR_LEXER_UNEXPECTED_INPUT;

This error is returned when a $ is encountered that is not at the end of an identifier. The other case:

    return ERROR_LEXER_UNEXPECTED_INPUT;

is returned when no valid Basic language token is parsed.

Based on this, but without looking at your program, I would guess they're either some invalid ASCII characters in the file, or the first issue of $ not at end of a variable. To further debug, try cutting your program in halves and loading it, successively until you find out the error. A line number is not valid possibly because the error is before the first line number?

@ghaerr
Copy link
Owner

ghaerr commented Jan 22, 2025

Oops - further inspection of the basic tokenization process shows that the program source is first loaded using a call to tokenize function:

    while (1) {
        ret = nextToken();
        if (ret) break;
    }

It appears during this process that program is merely being tokenized into a token input buffer, and no line numbers have yet been assigned. This is why the error does not display a line number. Let me look into how we might be able to learn where the tokenization got an error.

@ghaerr
Copy link
Owner

ghaerr commented Jan 22, 2025

I've tracked it down. Please apply this patch to basic/host.c, which should display the input line from which any tokenization error occurs. This will display the input line having the error, followed by the error. If this works, I'll prepare a PR for you.

diff --git a/elkscmd/basic/host.c b/elkscmd/basic/host.c
index b48c7288..5d92defd 100644
--- a/elkscmd/basic/host.c
+++ b/elkscmd/basic/host.c
@@ -342,6 +342,8 @@ static int loop(FILE *infile) {
         if (lineNumber != 0) {
             host_outputLong(lineNumber);
             host_outputChar('-');
+        } else {
+            printf("Tokenization error near '%s'\n", input);
         }
         printf("%s\n\n", errorTable[ret]);
     } else if (!infile)

@toncho11
Copy link
Contributor Author

So I put this in a file called basic_line_error.patch and I do

git apply /path/basic_line_error.patch ?

Actually it is hard for me to test because I just can not copy .bas files inside an image. I mount fat ELKS images with a special program on Windows. But it is a very laborious work.

@ghaerr
Copy link
Owner

ghaerr commented Jan 27, 2025

@toncho11,

For displayed patches, just do:

$ patch -p1 < patchfile

I've created PR #2202 since testing this isn't easy for you.

ELKS Basic is available as a host program hostbasic. It isn't built by default, but can be done so by:

$ cd elkscmd/basic
$ make host
./hostbasic

I plan to build all the host-available applications automatically, I'll try to get that done sooner.

it is hard for me to test because I just can not copy .bas files inside an image

I sometimes copy files to the ELKS /root before building an image, which makes things easier. To do this:

$ cp file1 file2 file3 elkscmd/rootfs_template/root
$ make

@toncho11
Copy link
Contributor Author

Thank you!
I was doing this with elkscmd/rootfs_template/root, but then I was using build.sh which first does a clean, so it was very slow. I will use just make now

hostbasic is a 64 bit version? Nice, but how is the graphic implemented then? Not sure I get it.

@ghaerr
Copy link
Owner

ghaerr commented Jan 27, 2025

hostbasic is a 64 bit version? Nice, but how is the graphic implemented then? Not sure I get it.

Yes. But no graphics in the host versions: each platform, host, ibmpc and pc98 have their own host-xxx.c platform file. I only suggested using hostbasic to quickly learn where your syntax error is, which is what this open issue is all about?

@toncho11
Copy link
Contributor Author

toncho11 commented Jan 27, 2025

Yes.
I was thinking how much easier will be to do the entire development and testing on the host.

SDL2 for C can be used for the host. In theory it should be easy to implement. I can look into this when I have time.

@ghaerr
Copy link
Owner

ghaerr commented Jan 27, 2025

SDL2 for C can be used for the host.

Yes. I'm quite familiar with SDL2 and have a full driver for that for the real Microwindows - but not sure it'd be worth the effort to build all that since 1) few people use ELKS basic, and 2) native support for ELKS basic would be far less resolution than would be available on the host. There would have to be work required to emulate the smaller resolution on the high resolution host, which involves additional effort.

@toncho11
Copy link
Contributor Author

I can not build the host basic. I am using gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0

:~/elks/elkscmd/basic$ make host
gcc -O3 basic.c host.c host-stubs.c ../../libc/misc/ecvt.c ../../libc/misc/dtostr.c -o hostbasic
/usr/bin/ld: /tmp/ccnb4ZyI.o: in function `parseFnCallExpr':
basic.c:(.text+0x3a4d): undefined reference to `powf'
/usr/bin/ld: /tmp/ccnb4ZyI.o: in function `parseMathFn':
basic.c:(.text+0x5670): undefined reference to `expf'
/usr/bin/ld: basic.c:(.text+0x56ec): undefined reference to `logf'
/usr/bin/ld: basic.c:(.text+0x5710): undefined reference to `cosf'
/usr/bin/ld: basic.c:(.text+0x573c): undefined reference to `sinf'
/usr/bin/ld: basic.c:(.text+0x577e): undefined reference to `tanf'
/usr/bin/ld: basic.c:(.text+0x57af): undefined reference to `acosf'
/usr/bin/ld: basic.c:(.text+0x57d6): undefined reference to `asinf'
/usr/bin/ld: basic.c:(.text+0x5813): undefined reference to `atanf'
collect2: error: ld returned 1 exit status
make: *** [Makefile:48: hostbasic] Error 1

@ghaerr
Copy link
Owner

ghaerr commented Jan 29, 2025

The math library is missing on Linux. Add -lm as follows to the Makefile:

hostbasic: $(HOSTSRC)
    $(HOSTCC) $(HOSTCFLAGS) $(HOSTSRC) -o $@ -lm

@toncho11
Copy link
Contributor Author

Thanks.
Underscore is not allowed as in line:
70 SCR_H = 200 ?

@ghaerr
Copy link
Owner

ghaerr commented Jan 30, 2025

Underscore is not allowed

Glad you were able to find the error. Where did gorilla.bas come from, another basic or did you write it yourself? I'm wondering whether we should consider allowing underscore to be in identifiers or not? If gorillas.bas is from another basic, we might want to allow it to be more compatible, otherwise we probably should not as other basics don't allow it.

@toncho11
Copy link
Contributor Author

It seems our basic does not support multi-line IF ELSE ...

@toncho11
Copy link
Contributor Author

Actually looking at basic.h it look like "ELSE" is not a supported token.
I am not an expert on basic ... and it seems the trouble with basic comes with the existence of too many dialects and supported/unsupported features.

@ghaerr
Copy link
Owner

ghaerr commented Jan 30, 2025

it seems the trouble with basic comes with the existence of too many dialects

Yes, that's definitely the case. I think our basic is pretty good, small and fast; I looked around a while before finding this one. It's language support is very similar to Sinclair Basic, but unfortunately there seem to be a ton of dialects and even extensions to Sinclair Basic. I remember running into this issue a while ago - of course an ELSE capability could be added, but even then we're not guaranteed it'd be compatible with other programs already written.

@toncho11
Copy link
Contributor Author

One solution that I am already using for Gorillas.bas is to give Chatgpt the list of supported features in our basic based on the README. You need to create a good prompt where the missing features are clearly explained. After that this prompt can be used many times to rewrite existing basic code into our dialect. It works, but not perfectly. Still this method can only get better with time.

@toncho11
Copy link
Contributor Author

@ghaerr Thanks for the line reporting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants