Skip to content

Commit 93646ef

Browse files
Add visit keyword support in Jac syntax highlighting (#40)
1 parent 74a4fab commit 93646ef

File tree

3 files changed

+133
-76
lines changed

3 files changed

+133
-76
lines changed

jaseci-org/lib/data/verticalTabs.js

Lines changed: 118 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -27,56 +27,67 @@ with entry {
2727
{
2828
filename: "oop_example.jac",
2929
code: `
30-
# --- Build a living, interconnected world with nodes and walkers ---
30+
node Library {
31+
has location: str;
32+
can search_shelves with borrower entry;
33+
}
3134
32-
node Landmark {
33-
has name: str;
34-
can react with Tourist entry {
35-
print("📸 Tourist visits", self.name);
36-
visit [-->];
37-
}
35+
node Shelf {
36+
has category: str;
37+
can check_books with borrower entry;
3838
}
3939
40-
node Cafe {
41-
can react with Tourist entry {
42-
print("☕ Tourist gets coffee and continues exploring.");
43-
visit [-->]; # flows to connected nodes
44-
}
40+
node Book {
41+
has title: str;
42+
has available: bool;
4543
}
4644
47-
node Local {
48-
can react with Tourist entry {
49-
print("👋 Local greets the Tourist");
50-
}
45+
walker borrower {
46+
has book_needed: str;
47+
can find_book with \`root entry;
5148
}
5249
53-
walker Tourist {
54-
has visited: list = [];
50+
with entry {
51+
# Building the world is just linking nodes
52+
lib1 = root ++> Library("Central Library");
53+
lib2 = root ++> Library("Community Library");
54+
55+
shelf1 = lib1 ++> Shelf("Fiction");
56+
shelf2 = lib1 ++> Shelf("Non-Fiction");
57+
shelf3 = lib2 ++> Shelf("Science");
5558
56-
can start_trip with \`root entry {
57-
print("🚶 Begins the journey at", here);
58-
visit [-->];
59-
}
60-
can log_visit with Landmark exit {
61-
self.visited.append(here.name);
62-
}
63-
can end_trip with exit {
64-
print("🏁 Trip ended. Places seen:", self.visited);
65-
}
59+
book1 = shelf1 ++> Book("1984", True);
60+
book2 = shelf1 ++> Book("Brave New World", False);
61+
book3 = shelf2 ++> Book("Sapiens", True);
62+
book4 = shelf3 ++> Book("A Brief History of Time", False);
63+
book5 = shelf3 ++> Book("The Selfish Gene", True);
64+
65+
borrower("1984") spawn root;
6666
}
6767
68-
with entry {
69-
# Build world
70-
root ++> Local();
71-
root ++> Landmark(name="Eiffel Tower");
72-
root ++> Cafe();
73-
root ++> Landmark(name="Colosseum");
74-
75-
# Send Tourist walking
76-
a = (root spawn Tourist());
77-
print("Tourist entity ID:", a.visited);
68+
impl Library.search_shelves {
69+
shelves = [self --> Shelf];
70+
visit shelves; # No loops, just visit
7871
}
79-
`,
72+
73+
impl Shelf.check_books {
74+
found_book = [self --> (\`?Book)](
75+
?title == visitor.book_needed, available == True
76+
);
77+
78+
if (found_book) {
79+
print(f"Borrowed: {found_book}");
80+
print(f"From Shelf: {self.category}");
81+
disengage; # Stop traversal cleanly
82+
} else {
83+
print("Book not available in shelf", self.category);
84+
}
85+
}
86+
87+
impl borrower.find_book {
88+
libraries = [here --> Library];
89+
visit libraries;
90+
}`,
8091
},
8192
{
8293
filename: "cloud_scaling.jac",
@@ -242,43 +253,75 @@ print(result)
242253
{
243254
filename: "oop_example.py",
244255
code: `
245-
class Landmark:
246-
def __init__(self, name):
256+
class Borrower:
257+
def __init__(self, name, book_needed):
247258
self.name = name
248-
249-
def react(self, tourist):
250-
print("📸 Tourist visits", self.name)
251-
tourist.visited.append(self.name)
252-
253-
class Cafe:
254-
def react(self, tourist):
255-
print("☕ Tourist gets coffee and continues exploring.")
256-
257-
class Local:
258-
def react(self, tourist):
259-
print("👋 Local greets the Tourist")
260-
261-
class Tourist:
262-
def __init__(self):
263-
self.visited = []
264-
265-
def start_trip(self, places):
266-
print("🚶 Begins the journey")
267-
for place in places:
268-
place.react(self)
269-
print("🏁 Trip ended. Places seen:", self.visited)
270-
271-
# Build world
272-
places = [
273-
Local(),
274-
Landmark("Eiffel Tower"),
275-
Cafe(),
276-
Landmark("Colosseum")
277-
]
278-
279-
# Send Tourist walking
280-
tourist = Tourist()
281-
tourist.start_trip(places)
259+
self.book_needed = book_needed
260+
self.libraries = []
261+
262+
class Library:
263+
def __init__(self, location):
264+
self.location = location
265+
self.shelves = []
266+
267+
class Shelf:
268+
def __init__(self, category):
269+
self.category = category
270+
self.books = []
271+
272+
class Book:
273+
def __init__(self, title, available=True):
274+
self.title = title
275+
self.available = available
276+
277+
borrower = Borrower("Reader", book_needed="1984")
278+
279+
lib1 = Library("Central Library")
280+
lib2 = Library("Community Library")
281+
borrower.libraries.extend([lib1, lib2])
282+
283+
shelf1 = Shelf("Fiction")
284+
shelf2 = Shelf("Non-Fiction")
285+
shelf3 = Shelf("Science")
286+
287+
lib1.shelves.extend([shelf1, shelf2])
288+
lib2.shelves.append(shelf3)
289+
290+
book1 = Book("1984", True)
291+
book2 = Book("Brave New World", False)
292+
book3 = Book("Sapiens", True)
293+
book4 = Book("A Brief History of Time", False)
294+
book5 = Book("The Selfish Gene", True)
295+
296+
shelf1.books.extend([book1, book2])
297+
shelf2.books.append(book3)
298+
shelf3.books.extend([book4, book5])
299+
300+
found_book = None
301+
found_shelf = None
302+
found_library = None
303+
libraries = borrower.libraries
304+
wanted = borrower.book_needed
305+
306+
# Nested loops everywhere
307+
for lib in libraries:
308+
for shelf in lib.shelves:
309+
for book in shelf.books:
310+
if book.title == wanted and book.available:
311+
found_book = book
312+
found_shelf = shelf
313+
found_library = lib
314+
break
315+
if found_book:
316+
break
317+
if found_book:
318+
break
319+
320+
if found_book:
321+
print(f"Borrowed: {found_book.title}")
322+
print(f"From Shelf: {found_shelf.category}")
323+
else:
324+
print("Book not available")
282325
`,
283326
},
284327
{

jaseci-org/lib/syntax/jacSyntax.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ pre[class*="language-"] {
129129
color: #c678dd;
130130
}
131131

132+
.jac-visit-keyword {
133+
color: #c678dd;
134+
}
135+
132136
.jac-module {
133137
color: #4ec9b0;
134138
}
@@ -197,4 +201,8 @@ pre[class*="language-"] {
197201

198202
.light .jac-special-keyword {
199203
color: #8250df;
204+
}
205+
206+
.light .jac-visit-keyword {
207+
color: #8250df;
200208
}

jaseci-org/lib/syntax/syntaxHighlighting.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export async function highlightJacCode(code: string): Promise<string> {
9090
return `<span class="jac-keyword">${escapeHtml(token.value)}</span>`;
9191
case 'special-keyword':
9292
return `<span class="jac-special-keyword">${escapeHtml(token.value)}</span>`;
93+
case 'visit-keyword':
94+
return `<span class="jac-visit-keyword">${escapeHtml(token.value)}</span>`;
9395
case 'type':
9496
return `<span class="jac-type">${escapeHtml(token.value)}</span>`;
9597
case 'class-name':
@@ -115,13 +117,15 @@ function tokenizeJacCode(code: string): Array<{type: string, value: string, leve
115117
const keywords = new Set([
116118
'node', 'edge', 'walker', 'can', 'with', 'entry', 'exit', 'def', 'class', 'obj',
117119
'enum', 'has', 'ability', 'if', 'else', 'elif', 'for', 'while', 'return',
118-
'spawn', 'visit', 'disengage', 'yield', 'try', 'except', 'finally', 'assert',
120+
'spawn', 'yield', 'try', 'except', 'finally', 'assert',
119121
'import', 'include', 'from', 'as', 'global', 'async', 'await', 'lambda',
120122
'here', 'self', 'root', 'super', 'init', 'postinit', 'visitor', 'impl',
121123
'and', 'or', 'not', 'in', 'is', 'True', 'False', 'None', 'break', 'continue',
122124
'pass', 'del', 'raise', 'test', 'check'
123125
]);
124126

127+
const visitKeywords = new Set(['visit', 'disengage']);
128+
125129
const types = new Set(['str', 'int', 'float', 'bool', 'list', 'dict', 'tuple', 'set', 'any', 'type']);
126130
const operators = new Set(['=', '+', '-', '*', '/', '%', '==', '!=', '<', '>', '<=', '>=', '+=', '-=', '*=', '/=', '|', '&', '^', '~', '<<', '>>', '**']);
127131

@@ -283,6 +287,8 @@ function tokenizeJacCode(code: string): Array<{type: string, value: string, leve
283287
// Special keywords like 'entry', 'exit' in certain contexts (check BEFORE general keywords)
284288
if (['entry', 'exit'].includes(identifier) && (isAfterWith || isAfterCan)) {
285289
tokens.push({ type: 'special-keyword', value: identifier });
290+
} else if (visitKeywords.has(identifier)) {
291+
tokens.push({ type: 'visit-keyword', value: identifier });
286292
} else if (keywords.has(identifier)) {
287293
tokens.push({ type: 'keyword', value: identifier });
288294
} else if (types.has(identifier)) {

0 commit comments

Comments
 (0)