Line Numbers on Library Reference Source Code [Adv3/Adv3Lite]

As it says on the tin.

I don’t know if this is a big ask or not.

When I get an error report and it gives me a line number for something in the original library source code, I need to go into the docs, open the library reference, find the source file entry, open the source file, copy the whole source code, and paste it into my notepad (which has line numbers), and then look up the line number given in the error to get an idea of how something I wrote might have broke something further in.

I’m using VSCode instead of the workbench because I’m on Linux.

The process of selecting, copying, and pasting the source code into a notepad to see line numbers is probably the most tedious part of the process. If there could be line numbers in the library reference docs, that would be amazing.

Again, though, I don’t know how difficult this request would be.

Thank you for your time!

EDIT: Y’know, sometimes I can be a mid-tier Linux wizard, and apparently sometimes I can miss the most obvious solutions of all time. Thank you for the solutions!

EDIT 2: I have combined multiple solutions into a handy script, found here!

less -N

best regards from Italy,
dott. Piergiorgio.

2 Likes

Poor Joey!! You can open all the library files in VSCode and get all the line #s displayed just like your game files. Just add the Lite folder to your project files…
Or maybe workspace is what I meant; not at the computer right now…

1 Like

But get this, I started writing my game with none other than TextEdit, and almost fell to the floor when I discovered BBEdit and discovered you can do a text search in multiple files at once

2 Likes

Also in linux, and because I like different debug v. edit windows, I have a terminal window just for TADS source debug. As I’m sure you know, VI lets you jump to line numbers with ‘<linenum>G’. This short bash script lets me >vt actions.t (name of script is vt, for ‘vi tads’), then ####G gets me to the line in question. VI syntax highlighting is easily confused, unfortunately, which makes VS a better readability option. But I just luuurves the snappy line number nav of VI.

#!/bin/bash
#
if [[ -f /usr/share/frobtads/tads3/lib/adv3/$1 ]]
then
     vi /usr/share/frobtads/tads3/lib/adv3/$1
else
     if [[ -f /usr/share/frobtads/tads3/lib/adv3/en_us/$1 ]]
     then
        vi /usr/share/frobtads/tads3/lib/adv3/en_us/$1
     else
     	if [[ -f /usr/share/frobtads/tads3/lib/extensions/$1 ]]
        then
     	     vi /usr/share/frobtads/tads3/lib/extensions/$1
        else
	         echo "File not found in adv3/, adv3/en_us/ or extensions/."
        fi
     fi
fi

EDIT: weird indenting fixed
Note ‘####G’ also works with Piergiorgio’s >less -N option

1 Like

On the command line you can also give vi a line number via vi +[line number], so vi +133 will open the editor scrolled to center around line 133.

The atom editor also displays line nunbers in the file view.

Note that T3 reports the return address of the frame that threw the exception, so most of the time the line number it displays is the first executable line following the one that actually caused the exception.

1 Like

(What did he mean by that…?)

Ohhhhhh he meant the less command for Linux!

Can’t tell if this is pity or annoyed sarcasm.

Y’know, this is exactly why I posted here, because I figured I might also be missing a really obvious solution.

Ohhhhhhhhh, I like this!

Since I use the terminal in VSCode to run stuff anyways, I might use some of your script code and @Piergiorgio_d_errico’s suggestion to make a similar handy little script!

Oh, yeah I’ve started to notice this. Good to know I’m not crazy.

1 Like

Sorry, not sarcasm! Genuine pity that you’ve had to fiddle like that so long… because I used to too…

1 Like

I’ll also point out that doing this (displaying the line of source that threw an exception plus a couple lines of context) is one of the design use cases for the interative-ish debugger. I posted last week.

It’s a little fiddly because T3 doesn’t consistently prefer full vs relative paths and by default some intepreters (like FrobTADS’ frob, which is what I’ve been using by default during development) will default to only allowing the interpreter to read files from the directory the game file was loaded from. But with a little tweaking you can get a workflow where you can do something like:

# t3make -d -a -f catch.t3m
     [compile output]
# frob gates/catch.t3
Void
This is a featureless void.

You see a pebble here.

>take pebble
[Runtime error: invalid datatypes for addition operator
->pebble.actionDobjTake() src/catch.t, line 65
   {obj:predicate(Take)}.execAction()
   [rest of stack trace snipped]
===breakpoint in pebble.actionDobjTake() src/catch.t, line 65===
===type HELP or ? for information on the interactive debugger===
>>> list
 060
 061   dobjFor(Take) {
 062       // This since foozle is nil, this will throw a runtime
 063       // error, dropping us into the debugger.
 064       action() {
>065           foozle += 1;
 066           inherited();
 067       }
 068   }
 069 ;
 070
>>> 

It doesn’t have anything like a full source navigator, no integrated editor, and you can’t do stepwise execution. So it’s definitely just a big ol’ ugly kludge, not a proper interactive debugger. But the first thing I want to do after the interpreter barfs is to look at the source that threw the exception, and this does that.

1 Like

Oh yeah! Does this work with Adv3Lite?

No idea. It is heavily dependent on T3’s reflection services, but I think most of those are common to both adv3 and adv3lite. If they’re not, then the debugger would more or less have to be rewritten from scratch to work with any library that doesn’t use the same reflection stuff.

The main thing that I expect would need to be tweaked is the exception handling in the main event loop. As written, the debugger just replaces runScheduler() from adv3/events.t, which is the main event loop in a adv3 game. I think all you’d have to do to make it work with adv3lite is do something similar with mainCommandLoop() in adv3lite/main.t but I don’t use adv3lite so this is just based on cursory source-reading.

1 Like

Okay, so I have modified the script that @jjmcc gave me:

#!/usr/bin/env bash

TADSLIBPATH=/usr/local/share/frobtads/tads3/lib
TADSLIBADV3LITEPATH=$TADSLIBPATH/adv3Lite

SRCFILENAME=$1
LINENUM=$2

LOOKCMD=code\ --goto

if [[ -f $TADSLIBADV3LITEPATH/$SRCFILENAME ]]
then
    $LOOKCMD $TADSLIBADV3LITEPATH/$SRCFILENAME:$LINENUM
else
    if [[ -f $TADSLIBADV3LITEPATH/en_us/$SRCFILENAME ]]
    then
        $LOOKCMD $TADSLIBADV3LITEPATH/en_us/$SRCFILENAME:$LINENUM
    else
     	if [[ -f $TADSLIBPATH/extensions/$SRCFILENAME ]]
        then
     	    $LOOKCMD $TADSLIBPATH/extensions/$SRCFILENAME:$LINENUM
        else
	        echo "$SRCFILENAME not found in adv3lite/, adv3lite/en_us/ or extensions/."
        fi
    fi
fi

(Named dtl.sh for “debug tads line”)

This works in VSCode, and you can run this from your workspace in the integrate terminal, and it opens the source file in a new tab, and automatically scrolls the the line you need. For example:

./dtl.sh action.t 57

This will open action.t and go to line 57!

This way I also get the syntax highlighting from the VSCode TADS3 extension!

Posting this here, in case anyone else finds this useful!

2 Likes

Update on using the debugger with adv3lite:

The reflection stuff is the same, and as I suspected the main thing required to get it to work was changing the exception handling hooks. A minor tweak to the action declaration of the >BREAKPOINT command was also required, as well as other fiddly bookkeeping stuff (changing all the #include <adv3.h>s to #include <advlite.h>s, and that kind of thing).

Anyway, it was just a couple minutes work, so here’s a repo of the adv3lite version of the debugger. I didn’t bother porting all of the demo examples to the “lite” repo, but they should all work the same way.

I don’t actively use adv3lite, so I’ve only done minimal testing, so let me know if you run into any problems.

1 Like

Nice!! I’ll check this out later tonight!