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

Develop release the v43 language support changes #1

Merged
merged 8 commits into from
Dec 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions spin2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ Possible next additions:
- Add new-file templates as Snippets
- Add additional Snippets as the community identifies them

## [2.2.11] 2023-12-30

Update P2 Only

- Add recognition of "auto" on debug scope display declarations
- Add semantic highlight color change for byte(), word(), and long() method overrides
- Add recognition of byte(), word(), and long() method names to provide method vs. storage type hover text
- Add recognition of {Spin2_v##} format Spin Language Requirement directive
- Emit any languge directive when used to generated interface documentation
- Add support for lstring() when {Spin2_v43} is specified
- Add detection of/error generation for duplicate declarations within CON, VAR and DAT sections

## [2.2.10] 2023-12-24

Update P1 and P2
Expand Down
11 changes: 9 additions & 2 deletions spin2/TEST_LANG_SERVER/spin2/231112-fixes.spin2
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
' --------------------------------------------------------------------------------------------------
' bitfield highlight issues Ln#32-34
' {Spin2_v43}

VAR

byte header_buf[$100]
byte header_buf[$100] ' <-- BUG should generate dupe of DAT variable declaration error

CON

SEGA_FOURCC = ("S"+"E"<<8+"G"<<16+"A"<<24)
SEGA_FOURCC = ("S"+"E"<<8+"G"<<16+"A"<<24) ' <-- BUG should generate P2 Spin dupe constant declaration

REGION_OVERSEAS_60HZ = %10 '' Americas
REGION_DOMESTIC_60HZ = %00 '' Japan
Expand Down Expand Up @@ -60,6 +62,9 @@ repeat (256*8)

PUB LEDon()

file_open(@"filename1", %"r+")
file_open(@"filename1", %"A+")

DoSETUP(string("Text",13)) 'turn on LEDs
DoSETUP(lstring("Hello",0,"Terve",0)) 'turn on LEDs
DoSETUP(byte($21,$09,$00,$02,$00,$00,$01,$00)) 'turn on LEDs
Expand All @@ -70,3 +75,5 @@ PUB LEDon()
DoSETUP(long(1e-6,1e-3,1.0,1e3,1e6,-50,BYTE $FF)) 'turn on LEDs

PRI DoSETUP(pBytes)

PRI file_open(pFilename, pOpenMode)
6 changes: 3 additions & 3 deletions spin2/TEST_LANG_SERVER/spin2/231116-fixes.spin2
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ VAR stack[30], clocks, sample, states
PUB go() | i, x, y, m, n
' lines 172-...
debug(`plot p title 'Five Buttons on a Single Pin' size 430 600 backcolor white update)
debug(`p set `(sch_x,sch_y-60) blue text 'clocks: `(clocks)) ' <--- untermnated string not highlighted
debug(`p set `(sch_x,sch_y-80) text 'sample: `(sample))
debug(`p set `(sch_x,sch_y-100) text 'states: `ubin_byte_(n))
debug(`p set `(sch_x,sch_y-60) blue text 'clocks: `(clocks)') ' <--- untermnated string not highlighted
debug(`p set `(sch_x,sch_y-80) text 'sample: `(sample)')
debug(`p set `(sch_x,sch_y-100) text 'states: `ubin_byte_(n)')
debug(`p update `dly(20))


Expand Down
16 changes: 15 additions & 1 deletion spin2/TEST_LANG_SERVER/spin2/231123-fixes.spin2
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
' --------------------
' test parsing of storagetype variable subpart access
' {Spin2_v41}

PUB main(param1) : retValue | local2
PUB main(param1) : retValue | LONG local2

test(param1.word[0])

Expand All @@ -13,3 +14,16 @@ PUB main(param1) : retValue | local2


PRI test(b)

PUB LEDon()

DoSETUP(string("Text",13)) 'turn on LEDs
DoSETUP(lstring("Hello",0,"Terve",0)) 'turn on LEDs
DoSETUP(byte($21,$09,$00,$02,$00,$00,$01,$00)) 'turn on LEDs
DoSETUP(byte($80,$09,$77,WORD $1234,LONG -1)) 'turn on LEDs
DoSETUP(word($21,$09,$00,$02,$00,$00,$01,$00)) 'turn on LEDs
DoSETUP(word(1_000,10_000,50_000,LONG $12345678)) 'turn on LEDs
DoSETUP(long($21,$09,$00,$02,$00,$00,$01,$00)) 'turn on LEDs
DoSETUP(long(1e-6,1e-3,1.0,1e3,1e6,-50,BYTE $FF)) 'turn on LEDs

PRI DoSETUP(pBytes)
17 changes: 17 additions & 0 deletions spin2/TEST_LANG_SERVER/spin2/231230-fixes.spin2
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

' --------------------
' test duplicate global detection

DAT

header_buf byte 0[$100]

VAR

byte header_buf[$100] ' <-- BUG should generate dupe of DAT variable declaration error
byte header_buf[$100] ' <-- BUG should generate P2 Spin dupe VAR varaible declaration error

CON

SEGA_FOURCC = ("S"+"E"<<8+"G"<<16+"A"<<24)
SEGA_FOURCC = ("S"+"E"<<8+"G"<<16+"A"<<24) ' <-- BUG should generate P2 Spin dupe constant declaration
4 changes: 2 additions & 2 deletions spin2/TEST_LANG_SERVER/spin2/debug_coloring_examples.spin2
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ PUB oscilloscope() | chanA, chanB, chanC
'' TASK: display oscilloscope waveforms

debug(`scope Scope1 pos 100 0 size 800 600 linesize 6) ' end of line comments
debug(`Scope1 'Analog Input' 0 3300 250 0 %1111 red) ' WARNING (if no comment here semantic highlight is BAD!!!)
debug(`Scope1 'Digital Output' 0 3300 250 300 %1111 green) ' end of line comments
debug(`Scope1 'Analog Input' 0 3300 250 0 %1111 red auto) ' WARNING (if no comment here semantic highlight is BAD!!!)
debug(`Scope1 'Digital Output' 0 3300 250 300 %1111 green auto) ' end of line comments
debug(`Scope1 samples 16 trigger -1)
debug(`term Term1 pos 914 71 size 30 1 textsize 20 color red) ' end of line comments
debug(`term Term2 pos 914 0 size 30 1 textsize 20 color green)
Expand Down
25 changes: 24 additions & 1 deletion spin2/client/src/providers/spin.document.generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ export class DocGenerator {
let textEditor = vscode.window.activeTextEditor;
if (textEditor) {
let endOfLineStr: string = textEditor.document.eol == EndOfLine.CRLF ? "\r\n" : "\n";
let bHuntingForVersion: boolean = true; // initially we re hunting for a {Spin2_v##} spec in file-top comments

var currentlyOpenTabfilePath = textEditor.document.uri.fsPath;
var currentlyOpenTabfolderName = path.dirname(currentlyOpenTabfilePath);
Expand Down Expand Up @@ -236,13 +237,22 @@ export class DocGenerator {
let priorState: eParseState = currState;

let pubsFound: number = 0;

let requiredLanguageVersion: number = 0;
//
// 1st pass: emit topfile doc comments then list of pub methods
//
for (let i = 0; i < textEditor.document.lineCount; i++) {
let line = textEditor.document.lineAt(i);
const lineNbr = i + 1;
const trimmedLine = line.text.trim();

if (bHuntingForVersion && this.spinCodeUtils.containsSpinLanguageSpec(trimmedLine)) {
bHuntingForVersion = false; // done we found it
requiredLanguageVersion = this.spinCodeUtils.versionFromSpinLanguageSpec(trimmedLine);
this.logMessage(`+ (DBG) generateDocument() requiredLanguageVersion=(${requiredLanguageVersion}) at Ln#${lineNbr} [${trimmedLine}]`);
}

if (currState == eParseState.inMultiLineDocComment) {
// skip all {{ --- }} multi-line doc comments
// in multi-line doc-comment, hunt for end '}}' to exit
Expand Down Expand Up @@ -315,13 +325,26 @@ export class DocGenerator {
// emit comment without leading ''
fs.appendFileSync(outFile, trimmedLine.substring(2) + endOfLineStr);
}
} else if (sectionStatus.isSectionStart && currState == eParseState.inPub) {
continue;
}

if (sectionStatus.isSectionStart && bHuntingForVersion) {
this.logMessage(`+ (DBG) generateDocument() STOP HUNT at Ln#${lineNbr} [${trimmedLine}]`);
bHuntingForVersion = false; // done, we passed the file-top comments. we can no longer search
}

if (sectionStatus.isSectionStart && currState == eParseState.inPub) {
// have public method report it
pubsFound++;
if (shouldEmitTopDocComments) {
this.logMessage(`+ (DBG) generateDocument() EMIT object header`);
fs.appendFileSync(outFile, "" + endOfLineStr); // blank line
const introText: string = 'Object "' + objectName + '" Interface:';
fs.appendFileSync(outFile, introText + endOfLineStr);
if (requiredLanguageVersion > 0) {
const lanVersionText: string = ` (Requires Spin2 Language v${requiredLanguageVersion})`;
fs.appendFileSync(outFile, lanVersionText + endOfLineStr);
}
fs.appendFileSync(outFile, "" + endOfLineStr); // blank line
}
shouldEmitTopDocComments = false; // no more of these!
Expand Down
44 changes: 44 additions & 0 deletions spin2/client/src/spin.code.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,48 @@ export class SpinCodeUtils {

return trimmedLine;
}

// borrowed from:
// dupe code at server/src/parser/spin.common.ts
//
public containsSpinLanguageSpec(line: string): boolean {
// return T/F where T means {Spin2_v##} was found in given string
const languageVersionRegEx = /\{Spin2\_v/i; // our version specification (just look for left edge)
return languageVersionRegEx.test(line);
}

public versionFromSpinLanguageSpec(line: string): number {
// return T/F where T means {Spin2_v##} was found in given string
let decodedVersion: number = 0; // return no version by default
const languageVersionRegEx = /\{Spin2\_v[0-9][0-9]\}/i; // our version specification - well formatted 0-99
const languageVersionThousandsRegEx = /\{Spin2\_v[0-9][0-9][0-9]\}/i; // our version specification - well formatted 0-999
const is3digit: boolean = languageVersionThousandsRegEx.test(line);
// if have fully formatted version
if (languageVersionRegEx.test(line) || is3digit) {
if (this.containsSpinLanguageSpec(line)) {
const matchText: string = "{Spin2_v".toLowerCase();
const verOffset: number = line.toLowerCase().indexOf(matchText);
if (verOffset != -1) {
if (is3digit) {
const hundreds: number = parseInt(line.charAt(verOffset + matchText.length));
const tens: number = parseInt(line.charAt(verOffset + matchText.length + 1));
const ones: number = parseInt(line.charAt(verOffset + matchText.length + 2));
decodedVersion = hundreds * 100 + tens * 10 + ones;
} else {
const tens: number = parseInt(line.charAt(verOffset + matchText.length));
const ones: number = parseInt(line.charAt(verOffset + matchText.length + 1));
decodedVersion = tens * 10 + ones;
}
}
// special: disallow unreleased versions:
// - 41 is base version so say 0
// - 42 was not released so say zero
// - 40 or less is also 0
if (decodedVersion < 43) {
decodedVersion = 0;
}
}
}
return decodedVersion;
}
}
2 changes: 1 addition & 1 deletion spin2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"icon": "images/Propeller.ico",
"author": "IronSheep",
"license": "MIT",
"version": "2.2.10",
"version": "2.2.11",
"repository": {
"type": "git",
"url": "https://github.com/ironsheep/P2-vscode-langserv-extension"
Expand Down
2 changes: 1 addition & 1 deletion spin2/scripts/LIVE-package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"icon": "images/Propeller.ico",
"author": "IronSheep",
"license": "MIT",
"version": "2.2.10",
"version": "2.2.11",
"repository": {
"type": "git",
"url": "https://github.com/ironsheep/P2-vscode-langserv-extension"
Expand Down
2 changes: 1 addition & 1 deletion spin2/scripts/TEST-package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "P1 and P2 Spin/Pasm Syntax/Semantic Highlighting w/Code Outline, Object Outline and Custom tabbing support",
"author": "IronSheep",
"license": "MIT",
"version": "2.2.10",
"version": "2.2.11",
"repository": {
"type": "git",
"url": "https://github.com/ironsheep/P2-vscode-langserv-extension"
Expand Down
46 changes: 46 additions & 0 deletions spin2/server/src/parser/spin.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,52 @@ export function haveDebugLine(line: string, startsWith: boolean = false): boolea
return startsWith ? debugStatementOpenStartRegEx.test(line) : debugStatementOpenRegEx.test(line);
}

export function isMethodCall(line: string): boolean {
const methodOpenRegEx = /^\s*\(/; // match zero or more whitespace before '(' from left edge of string
return methodOpenRegEx.test(line);
}

export function containsSpinLanguageSpec(line: string): boolean {
// return T/F where T means {Spin2_v##} was found in given string
const languageVersionRegEx = /\{Spin2\_v/i; // our version specification (just look for left edge)
return languageVersionRegEx.test(line);
}

export function versionFromSpinLanguageSpec(line: string): number {
// return T/F where T means {Spin2_v##} was found in given string
let decodedVersion: number = 0; // return no version by default
const languageVersionRegEx = /\{Spin2\_v[0-9][0-9]\}/i; // our version specification - well formatted 0-99
const languageVersionThousandsRegEx = /\{Spin2\_v[0-9][0-9][0-9]\}/i; // our version specification - well formatted 0-999
const is3digit: boolean = languageVersionThousandsRegEx.test(line);
// if have fully formatted version
if (languageVersionRegEx.test(line) || is3digit) {
if (containsSpinLanguageSpec(line)) {
const matchText: string = "{Spin2_v".toLowerCase();
const verOffset: number = line.toLowerCase().indexOf(matchText);
if (verOffset != -1) {
if (is3digit) {
const hundreds: number = parseInt(line.charAt(verOffset + matchText.length));
const tens: number = parseInt(line.charAt(verOffset + matchText.length + 1));
const ones: number = parseInt(line.charAt(verOffset + matchText.length + 2));
decodedVersion = hundreds * 100 + tens * 10 + ones;
} else {
const tens: number = parseInt(line.charAt(verOffset + matchText.length));
const ones: number = parseInt(line.charAt(verOffset + matchText.length + 1));
decodedVersion = tens * 10 + ones;
}
}
// special: disallow unreleased versions:
// - 41 is base version so say 0
// - 42 was not released so say zero
// - 40 or less is also 0
if (decodedVersion < 43) {
decodedVersion = 0;
}
}
}
return decodedVersion;
}

export class SpinControlFlowTracker {
private flowStatementStack: ICurrControlStatement[] = []; // nested statement tracking
private flowLogEnabled: boolean = false;
Expand Down
6 changes: 3 additions & 3 deletions spin2/server/src/parser/spin.extension.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export class ExtensionUtils {
cursorPosition: lsp.Position,
isInBlockComment: boolean,
inPasmCodeStatus: boolean
): [boolean, string, string, lsp.Position] {
): [boolean, string, string, lsp.Position, lsp.Position] {
const lineText = DocumentLineAt(document, wordPosition).trimEnd();
const P2_LOCAL_LABEL_PREFIX: string = ".";
const P1_LOCAL_LABEL_PREFIX: string = ":";
Expand Down Expand Up @@ -180,14 +180,14 @@ export class ExtensionUtils {
}
if (!wordRange || this.isPositionInString(lineText, wordPosition, stringsFound, ticVarsFound) || bPositionInComment || word.match(/^\d+.?\d+$/) || spinControlFlowKeywords.indexOf(word) > 0) {
this._logMessage(`+ sp2Utils: adjustWordPosition() EXIT false`);
return [false, null!, null!, null!];
return [false, null!, null!, null!, null!];
}
if (PositionIsEqual(wordPosition, wordRange.end) && PositionIsAfter(wordPosition, wordRange.start)) {
wordPosition = PositionTranslate(wordPosition, 0, -1);
}

this._logMessage(`+ sp2Utils: adjustWordPosition() EXIT true`);
return [true, objectRef, word, wordPosition];
return [true, objectRef, word, wordPosition, wordRange.start];
}

public isPositionInString(lineText: string, position: lsp.Position, stringsInLine: IPairs[], ticVarsInLine: IPairs[]): boolean {
Expand Down
Loading