@holoscript/robotics-plugin 1.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/examples/isaac-lab-sim-to-real-bridge.holo +63 -0
- package/examples/isaac-lab-sim-to-real.holo +127 -0
- package/package.json +7 -42
- package/python/isaac_lab_bridge.py +157 -0
- package/src/__tests__/isaac-lab-interop.test.ts +210 -0
- package/src/ast.ts +80 -0
- package/src/index.ts +563 -0
- package/src/lexer.ts +307 -0
- package/src/parser.ts +473 -0
- package/src/traits/ROS2HardwareLoopTrait.ts +84 -0
- package/src/traits/types.ts +4 -0
- package/src/usd-codegen.ts +651 -0
- package/tsconfig.json +10 -0
- package/vitest.config.ts +11 -0
- package/README.md +0 -3
- package/dist/ast.d.ts +0 -21
- package/dist/ast.js +0 -5
- package/dist/index.d.ts +0 -58
- package/dist/index.js +0 -44
- package/dist/lexer.d.ts +0 -52
- package/dist/lexer.js +0 -275
- package/dist/parser.d.ts +0 -22
- package/dist/parser.js +0 -202
- package/dist/usd-codegen.d.ts +0 -18
- package/dist/usd-codegen.js +0 -361
- package/examples/robot-arm-complete.holo +0 -199
- package/python/ros2_bridge.py +0 -77
package/dist/index.d.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @holoscript/robotics-plugin v1.0.0
|
|
3
|
-
* Complete robotics solution: Compile-time (USD/URDF) + Runtime (ROS2/Gazebo)
|
|
4
|
-
*
|
|
5
|
-
* Features:
|
|
6
|
-
* - USD codegen for NVIDIA Isaac Sim (from holoscript-compiler)
|
|
7
|
-
* - URDF/SDF export for ROS2/Gazebo
|
|
8
|
-
* - ROS2 runtime integration (roslibjs)
|
|
9
|
-
* - VR teleoperation and digital twins
|
|
10
|
-
*
|
|
11
|
-
* @packageDocumentation
|
|
12
|
-
*/
|
|
13
|
-
export { USDCodeGen } from './usd-codegen';
|
|
14
|
-
export { Lexer, Token, TokenType } from './lexer';
|
|
15
|
-
export { Parser } from './parser';
|
|
16
|
-
export * from './ast';
|
|
17
|
-
export interface ROS2Config {
|
|
18
|
-
ros_bridge_url: string;
|
|
19
|
-
namespace?: string;
|
|
20
|
-
tf_prefix?: string;
|
|
21
|
-
}
|
|
22
|
-
export interface GazeboConfig {
|
|
23
|
-
world_file?: string;
|
|
24
|
-
model_sdf?: string;
|
|
25
|
-
spawn_position?: [number, number, number];
|
|
26
|
-
}
|
|
27
|
-
export interface RobotJoint {
|
|
28
|
-
name: string;
|
|
29
|
-
type: 'revolute' | 'prismatic' | 'fixed' | 'continuous';
|
|
30
|
-
parent_link: string;
|
|
31
|
-
child_link: string;
|
|
32
|
-
axis?: [number, number, number];
|
|
33
|
-
limits?: {
|
|
34
|
-
lower: number;
|
|
35
|
-
upper: number;
|
|
36
|
-
effort: number;
|
|
37
|
-
velocity: number;
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
export interface RobotLink {
|
|
41
|
-
name: string;
|
|
42
|
-
inertial?: {
|
|
43
|
-
mass: number;
|
|
44
|
-
inertia: number[];
|
|
45
|
-
};
|
|
46
|
-
visual?: {
|
|
47
|
-
geometry: string;
|
|
48
|
-
material?: string;
|
|
49
|
-
};
|
|
50
|
-
collision?: {
|
|
51
|
-
geometry: string;
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
export declare const VERSION = "1.0.0";
|
|
55
|
-
declare const _default: {
|
|
56
|
-
VERSION: string;
|
|
57
|
-
};
|
|
58
|
-
export default _default;
|
package/dist/index.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @holoscript/robotics-plugin v1.0.0
|
|
4
|
-
* Complete robotics solution: Compile-time (USD/URDF) + Runtime (ROS2/Gazebo)
|
|
5
|
-
*
|
|
6
|
-
* Features:
|
|
7
|
-
* - USD codegen for NVIDIA Isaac Sim (from holoscript-compiler)
|
|
8
|
-
* - URDF/SDF export for ROS2/Gazebo
|
|
9
|
-
* - ROS2 runtime integration (roslibjs)
|
|
10
|
-
* - VR teleoperation and digital twins
|
|
11
|
-
*
|
|
12
|
-
* @packageDocumentation
|
|
13
|
-
*/
|
|
14
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
-
}
|
|
20
|
-
Object.defineProperty(o, k2, desc);
|
|
21
|
-
}) : (function(o, m, k, k2) {
|
|
22
|
-
if (k2 === undefined) k2 = k;
|
|
23
|
-
o[k2] = m[k];
|
|
24
|
-
}));
|
|
25
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
26
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.VERSION = exports.Parser = exports.TokenType = exports.Lexer = exports.USDCodeGen = void 0;
|
|
30
|
-
// Compile-time: USD/URDF codegen (from holoscript-compiler)
|
|
31
|
-
var usd_codegen_1 = require("./usd-codegen");
|
|
32
|
-
Object.defineProperty(exports, "USDCodeGen", { enumerable: true, get: function () { return usd_codegen_1.USDCodeGen; } });
|
|
33
|
-
var lexer_1 = require("./lexer");
|
|
34
|
-
Object.defineProperty(exports, "Lexer", { enumerable: true, get: function () { return lexer_1.Lexer; } });
|
|
35
|
-
Object.defineProperty(exports, "TokenType", { enumerable: true, get: function () { return lexer_1.TokenType; } });
|
|
36
|
-
var parser_1 = require("./parser");
|
|
37
|
-
Object.defineProperty(exports, "Parser", { enumerable: true, get: function () { return parser_1.Parser; } });
|
|
38
|
-
__exportStar(require("./ast"), exports);
|
|
39
|
-
// Version
|
|
40
|
-
exports.VERSION = '1.0.0';
|
|
41
|
-
// Re-export for convenience
|
|
42
|
-
exports.default = {
|
|
43
|
-
VERSION: exports.VERSION,
|
|
44
|
-
};
|
package/dist/lexer.d.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HoloScript Lexer (Tokenizer)
|
|
3
|
-
*
|
|
4
|
-
* Converts HoloScript source code into a stream of tokens for parsing.
|
|
5
|
-
* Supports: keywords, identifiers, traits (@trait), strings, numbers, symbols
|
|
6
|
-
*/
|
|
7
|
-
export declare enum TokenType {
|
|
8
|
-
KEYWORD = "KEYWORD",// composition, object, using, template, group
|
|
9
|
-
IDENTIFIER = "IDENTIFIER",// variable_name, link1, base
|
|
10
|
-
TRAIT = "TRAIT",// @joint_revolute, @force_sensor
|
|
11
|
-
STRING = "STRING",// "Base", "metal", "cylinder"
|
|
12
|
-
NUMBER = "NUMBER",// 0.1, 3.14, 100, -2.0
|
|
13
|
-
LBRACE = "LBRACE",// {
|
|
14
|
-
RBRACE = "RBRACE",// }
|
|
15
|
-
LBRACKET = "LBRACKET",// [
|
|
16
|
-
RBRACKET = "RBRACKET",// ]
|
|
17
|
-
COLON = "COLON",// :
|
|
18
|
-
COMMA = "COMMA",// ,
|
|
19
|
-
COMMENT = "COMMENT",// // comment
|
|
20
|
-
EOF = "EOF"
|
|
21
|
-
}
|
|
22
|
-
export interface Token {
|
|
23
|
-
type: TokenType;
|
|
24
|
-
value: string;
|
|
25
|
-
line: number;
|
|
26
|
-
column: number;
|
|
27
|
-
}
|
|
28
|
-
export declare class Lexer {
|
|
29
|
-
private source;
|
|
30
|
-
private position;
|
|
31
|
-
private line;
|
|
32
|
-
private column;
|
|
33
|
-
private tokens;
|
|
34
|
-
private readonly keywords;
|
|
35
|
-
constructor(source: string);
|
|
36
|
-
tokenize(): Token[];
|
|
37
|
-
private scanToken;
|
|
38
|
-
private scanTrait;
|
|
39
|
-
private scanString;
|
|
40
|
-
private scanNumber;
|
|
41
|
-
private scanIdentifierOrKeyword;
|
|
42
|
-
private scanSymbol;
|
|
43
|
-
private skipWhitespace;
|
|
44
|
-
private skipComment;
|
|
45
|
-
private currentChar;
|
|
46
|
-
private peek;
|
|
47
|
-
private advance;
|
|
48
|
-
private isWhitespace;
|
|
49
|
-
private isDigit;
|
|
50
|
-
private isAlpha;
|
|
51
|
-
private isAlphaNumericOrUnderscore;
|
|
52
|
-
}
|
package/dist/lexer.js
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* HoloScript Lexer (Tokenizer)
|
|
4
|
-
*
|
|
5
|
-
* Converts HoloScript source code into a stream of tokens for parsing.
|
|
6
|
-
* Supports: keywords, identifiers, traits (@trait), strings, numbers, symbols
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.Lexer = exports.TokenType = void 0;
|
|
10
|
-
var TokenType;
|
|
11
|
-
(function (TokenType) {
|
|
12
|
-
// Keywords
|
|
13
|
-
TokenType["KEYWORD"] = "KEYWORD";
|
|
14
|
-
// Identifiers & Traits
|
|
15
|
-
TokenType["IDENTIFIER"] = "IDENTIFIER";
|
|
16
|
-
TokenType["TRAIT"] = "TRAIT";
|
|
17
|
-
TokenType["STRING"] = "STRING";
|
|
18
|
-
TokenType["NUMBER"] = "NUMBER";
|
|
19
|
-
// Symbols
|
|
20
|
-
TokenType["LBRACE"] = "LBRACE";
|
|
21
|
-
TokenType["RBRACE"] = "RBRACE";
|
|
22
|
-
TokenType["LBRACKET"] = "LBRACKET";
|
|
23
|
-
TokenType["RBRACKET"] = "RBRACKET";
|
|
24
|
-
TokenType["COLON"] = "COLON";
|
|
25
|
-
TokenType["COMMA"] = "COMMA";
|
|
26
|
-
// Special
|
|
27
|
-
TokenType["COMMENT"] = "COMMENT";
|
|
28
|
-
TokenType["EOF"] = "EOF";
|
|
29
|
-
})(TokenType || (exports.TokenType = TokenType = {}));
|
|
30
|
-
class Lexer {
|
|
31
|
-
constructor(source) {
|
|
32
|
-
this.position = 0;
|
|
33
|
-
this.line = 1;
|
|
34
|
-
this.column = 1;
|
|
35
|
-
this.tokens = [];
|
|
36
|
-
this.keywords = new Set([
|
|
37
|
-
'composition',
|
|
38
|
-
'object',
|
|
39
|
-
'using',
|
|
40
|
-
'template',
|
|
41
|
-
'group',
|
|
42
|
-
'scene',
|
|
43
|
-
]);
|
|
44
|
-
this.source = source;
|
|
45
|
-
}
|
|
46
|
-
tokenize() {
|
|
47
|
-
while (this.position < this.source.length) {
|
|
48
|
-
this.scanToken();
|
|
49
|
-
}
|
|
50
|
-
this.tokens.push({
|
|
51
|
-
type: TokenType.EOF,
|
|
52
|
-
value: '',
|
|
53
|
-
line: this.line,
|
|
54
|
-
column: this.column,
|
|
55
|
-
});
|
|
56
|
-
return this.tokens;
|
|
57
|
-
}
|
|
58
|
-
scanToken() {
|
|
59
|
-
const char = this.currentChar();
|
|
60
|
-
// Skip whitespace
|
|
61
|
-
if (this.isWhitespace(char)) {
|
|
62
|
-
this.skipWhitespace();
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
// Comments
|
|
66
|
-
if (char === '/' && this.peek() === '/') {
|
|
67
|
-
this.skipComment();
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
// Traits (@identifier)
|
|
71
|
-
if (char === '@') {
|
|
72
|
-
this.scanTrait();
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
// String literals ("...")
|
|
76
|
-
if (char === '"') {
|
|
77
|
-
this.scanString();
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
// Numbers (0.1, 3.14, -2.0)
|
|
81
|
-
if (this.isDigit(char) || (char === '-' && this.isDigit(this.peek()))) {
|
|
82
|
-
this.scanNumber();
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
// Keywords & Identifiers
|
|
86
|
-
if (this.isAlpha(char)) {
|
|
87
|
-
this.scanIdentifierOrKeyword();
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
// Single-character tokens
|
|
91
|
-
this.scanSymbol(char);
|
|
92
|
-
}
|
|
93
|
-
scanTrait() {
|
|
94
|
-
const startLine = this.line;
|
|
95
|
-
const startColumn = this.column;
|
|
96
|
-
this.advance(); // Skip '@'
|
|
97
|
-
let trait = '';
|
|
98
|
-
while (this.position < this.source.length && this.isAlphaNumericOrUnderscore(this.currentChar())) {
|
|
99
|
-
trait += this.currentChar();
|
|
100
|
-
this.advance();
|
|
101
|
-
}
|
|
102
|
-
this.tokens.push({
|
|
103
|
-
type: TokenType.TRAIT,
|
|
104
|
-
value: trait,
|
|
105
|
-
line: startLine,
|
|
106
|
-
column: startColumn,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
scanString() {
|
|
110
|
-
const startLine = this.line;
|
|
111
|
-
const startColumn = this.column;
|
|
112
|
-
this.advance(); // Skip opening "
|
|
113
|
-
let str = '';
|
|
114
|
-
while (this.position < this.source.length && this.currentChar() !== '"') {
|
|
115
|
-
if (this.currentChar() === '\\') {
|
|
116
|
-
// Handle escape sequences
|
|
117
|
-
this.advance();
|
|
118
|
-
if (this.position < this.source.length) {
|
|
119
|
-
str += this.currentChar();
|
|
120
|
-
this.advance();
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
str += this.currentChar();
|
|
125
|
-
this.advance();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
if (this.currentChar() === '"') {
|
|
129
|
-
this.advance(); // Skip closing "
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
throw new Error(`Unterminated string at line ${startLine}, column ${startColumn}`);
|
|
133
|
-
}
|
|
134
|
-
this.tokens.push({
|
|
135
|
-
type: TokenType.STRING,
|
|
136
|
-
value: str,
|
|
137
|
-
line: startLine,
|
|
138
|
-
column: startColumn,
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
scanNumber() {
|
|
142
|
-
const startLine = this.line;
|
|
143
|
-
const startColumn = this.column;
|
|
144
|
-
let num = '';
|
|
145
|
-
// Handle negative sign
|
|
146
|
-
if (this.currentChar() === '-') {
|
|
147
|
-
num += this.currentChar();
|
|
148
|
-
this.advance();
|
|
149
|
-
}
|
|
150
|
-
// Integer part
|
|
151
|
-
while (this.position < this.source.length && this.isDigit(this.currentChar())) {
|
|
152
|
-
num += this.currentChar();
|
|
153
|
-
this.advance();
|
|
154
|
-
}
|
|
155
|
-
// Decimal part
|
|
156
|
-
if (this.currentChar() === '.' && this.isDigit(this.peek())) {
|
|
157
|
-
num += this.currentChar();
|
|
158
|
-
this.advance();
|
|
159
|
-
while (this.position < this.source.length && this.isDigit(this.currentChar())) {
|
|
160
|
-
num += this.currentChar();
|
|
161
|
-
this.advance();
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
this.tokens.push({
|
|
165
|
-
type: TokenType.NUMBER,
|
|
166
|
-
value: num,
|
|
167
|
-
line: startLine,
|
|
168
|
-
column: startColumn,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
scanIdentifierOrKeyword() {
|
|
172
|
-
const startLine = this.line;
|
|
173
|
-
const startColumn = this.column;
|
|
174
|
-
let ident = '';
|
|
175
|
-
while (this.position < this.source.length && this.isAlphaNumericOrUnderscore(this.currentChar())) {
|
|
176
|
-
ident += this.currentChar();
|
|
177
|
-
this.advance();
|
|
178
|
-
}
|
|
179
|
-
const type = this.keywords.has(ident) ? TokenType.KEYWORD : TokenType.IDENTIFIER;
|
|
180
|
-
this.tokens.push({
|
|
181
|
-
type,
|
|
182
|
-
value: ident,
|
|
183
|
-
line: startLine,
|
|
184
|
-
column: startColumn,
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
scanSymbol(char) {
|
|
188
|
-
const symbolMap = {
|
|
189
|
-
'{': TokenType.LBRACE,
|
|
190
|
-
'}': TokenType.RBRACE,
|
|
191
|
-
'[': TokenType.LBRACKET,
|
|
192
|
-
']': TokenType.RBRACKET,
|
|
193
|
-
':': TokenType.COLON,
|
|
194
|
-
',': TokenType.COMMA,
|
|
195
|
-
};
|
|
196
|
-
const tokenType = symbolMap[char];
|
|
197
|
-
if (tokenType) {
|
|
198
|
-
this.tokens.push({
|
|
199
|
-
type: tokenType,
|
|
200
|
-
value: char,
|
|
201
|
-
line: this.line,
|
|
202
|
-
column: this.column,
|
|
203
|
-
});
|
|
204
|
-
this.advance();
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
throw new Error(`Unexpected character '${char}' at line ${this.line}, column ${this.column}`);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
skipWhitespace() {
|
|
211
|
-
while (this.position < this.source.length && this.isWhitespace(this.currentChar())) {
|
|
212
|
-
if (this.currentChar() === '\n') {
|
|
213
|
-
this.line++;
|
|
214
|
-
this.column = 1;
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
this.column++;
|
|
218
|
-
}
|
|
219
|
-
this.position++;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
skipComment() {
|
|
223
|
-
// Skip until end of line
|
|
224
|
-
while (this.position < this.source.length && this.currentChar() !== '\n') {
|
|
225
|
-
this.position++;
|
|
226
|
-
this.column++;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
currentChar() {
|
|
230
|
-
return this.source[this.position] || '';
|
|
231
|
-
}
|
|
232
|
-
peek(offset = 1) {
|
|
233
|
-
const peekPos = this.position + offset;
|
|
234
|
-
return this.source[peekPos] || '';
|
|
235
|
-
}
|
|
236
|
-
advance() {
|
|
237
|
-
this.position++;
|
|
238
|
-
this.column++;
|
|
239
|
-
}
|
|
240
|
-
isWhitespace(char) {
|
|
241
|
-
return /\s/.test(char);
|
|
242
|
-
}
|
|
243
|
-
isDigit(char) {
|
|
244
|
-
return /[0-9]/.test(char);
|
|
245
|
-
}
|
|
246
|
-
isAlpha(char) {
|
|
247
|
-
return /[a-z_]/i.test(char);
|
|
248
|
-
}
|
|
249
|
-
isAlphaNumericOrUnderscore(char) {
|
|
250
|
-
return /[a-z0-9_]/i.test(char);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
exports.Lexer = Lexer;
|
|
254
|
-
// Example usage
|
|
255
|
-
if (require.main === module) {
|
|
256
|
-
const source = `
|
|
257
|
-
composition "TwoLinkArm" {
|
|
258
|
-
object "Base" @static {
|
|
259
|
-
geometry: "cylinder"
|
|
260
|
-
dimensions: [0.1, 0.05]
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
object "Link1" @joint_revolute {
|
|
264
|
-
joint_axis: [0, 0, 1]
|
|
265
|
-
joint_limits: [-3.14, 3.14]
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
`;
|
|
269
|
-
const lexer = new Lexer(source);
|
|
270
|
-
const tokens = lexer.tokenize();
|
|
271
|
-
console.log('Tokens:');
|
|
272
|
-
tokens.forEach((token, i) => {
|
|
273
|
-
console.log(`${i}: ${token.type.padEnd(15)} "${token.value}" (L${token.line}:C${token.column})`);
|
|
274
|
-
});
|
|
275
|
-
}
|
package/dist/parser.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HoloScript Parser
|
|
3
|
-
*
|
|
4
|
-
* Converts token stream into Abstract Syntax Tree (AST).
|
|
5
|
-
* Uses recursive descent parsing.
|
|
6
|
-
*/
|
|
7
|
-
import { Token } from './lexer';
|
|
8
|
-
import { CompositionNode } from './ast';
|
|
9
|
-
export declare class Parser {
|
|
10
|
-
private tokens;
|
|
11
|
-
private position;
|
|
12
|
-
constructor(tokens: Token[]);
|
|
13
|
-
parse(): CompositionNode;
|
|
14
|
-
private currentToken;
|
|
15
|
-
private peek;
|
|
16
|
-
private advance;
|
|
17
|
-
private expect;
|
|
18
|
-
private parseComposition;
|
|
19
|
-
private parseObject;
|
|
20
|
-
private parseValue;
|
|
21
|
-
private parseArray;
|
|
22
|
-
}
|
package/dist/parser.js
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* HoloScript Parser
|
|
4
|
-
*
|
|
5
|
-
* Converts token stream into Abstract Syntax Tree (AST).
|
|
6
|
-
* Uses recursive descent parsing.
|
|
7
|
-
*/
|
|
8
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
-
if (k2 === undefined) k2 = k;
|
|
10
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
-
}
|
|
14
|
-
Object.defineProperty(o, k2, desc);
|
|
15
|
-
}) : (function(o, m, k, k2) {
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
o[k2] = m[k];
|
|
18
|
-
}));
|
|
19
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
-
}) : function(o, v) {
|
|
22
|
-
o["default"] = v;
|
|
23
|
-
});
|
|
24
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
-
var ownKeys = function(o) {
|
|
26
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
-
var ar = [];
|
|
28
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
-
return ar;
|
|
30
|
-
};
|
|
31
|
-
return ownKeys(o);
|
|
32
|
-
};
|
|
33
|
-
return function (mod) {
|
|
34
|
-
if (mod && mod.__esModule) return mod;
|
|
35
|
-
var result = {};
|
|
36
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
-
__setModuleDefault(result, mod);
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
})();
|
|
41
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.Parser = void 0;
|
|
43
|
-
const lexer_1 = require("./lexer");
|
|
44
|
-
class Parser {
|
|
45
|
-
constructor(tokens) {
|
|
46
|
-
this.position = 0;
|
|
47
|
-
this.tokens = tokens;
|
|
48
|
-
}
|
|
49
|
-
parse() {
|
|
50
|
-
return this.parseComposition();
|
|
51
|
-
}
|
|
52
|
-
currentToken() {
|
|
53
|
-
const token = this.tokens[this.position];
|
|
54
|
-
if (!token) {
|
|
55
|
-
throw new Error('Unexpected end of input');
|
|
56
|
-
}
|
|
57
|
-
return token;
|
|
58
|
-
}
|
|
59
|
-
peek(offset = 1) {
|
|
60
|
-
const pos = this.position + offset;
|
|
61
|
-
const token = pos < this.tokens.length ? this.tokens[pos] : this.tokens[this.tokens.length - 1];
|
|
62
|
-
if (!token) {
|
|
63
|
-
throw new Error('Unexpected end of input');
|
|
64
|
-
}
|
|
65
|
-
return token;
|
|
66
|
-
}
|
|
67
|
-
advance() {
|
|
68
|
-
const token = this.currentToken();
|
|
69
|
-
this.position++;
|
|
70
|
-
return token;
|
|
71
|
-
}
|
|
72
|
-
expect(type, value) {
|
|
73
|
-
const token = this.currentToken();
|
|
74
|
-
if (token.type !== type) {
|
|
75
|
-
throw new Error(`Expected ${type}${value ? ` "${value}"` : ''} but got ${token.type} "${token.value}" at line ${token.line}, column ${token.column}`);
|
|
76
|
-
}
|
|
77
|
-
if (value !== undefined && token.value !== value) {
|
|
78
|
-
throw new Error(`Expected "${value}" but got "${token.value}" at line ${token.line}, column ${token.column}`);
|
|
79
|
-
}
|
|
80
|
-
return this.advance();
|
|
81
|
-
}
|
|
82
|
-
parseComposition() {
|
|
83
|
-
const startToken = this.expect(lexer_1.TokenType.KEYWORD, 'composition');
|
|
84
|
-
const name = this.expect(lexer_1.TokenType.STRING).value;
|
|
85
|
-
this.expect(lexer_1.TokenType.LBRACE);
|
|
86
|
-
const objects = [];
|
|
87
|
-
while (this.currentToken().type !== lexer_1.TokenType.RBRACE && this.currentToken().type !== lexer_1.TokenType.EOF) {
|
|
88
|
-
objects.push(this.parseObject());
|
|
89
|
-
}
|
|
90
|
-
this.expect(lexer_1.TokenType.RBRACE);
|
|
91
|
-
return {
|
|
92
|
-
type: 'composition',
|
|
93
|
-
name,
|
|
94
|
-
objects,
|
|
95
|
-
line: startToken.line,
|
|
96
|
-
column: startToken.column,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
parseObject() {
|
|
100
|
-
const startToken = this.expect(lexer_1.TokenType.KEYWORD, 'object');
|
|
101
|
-
const name = this.expect(lexer_1.TokenType.STRING).value;
|
|
102
|
-
// Parse traits (@trait1 @trait2 ...)
|
|
103
|
-
const traits = [];
|
|
104
|
-
while (this.currentToken().type === lexer_1.TokenType.TRAIT) {
|
|
105
|
-
traits.push(this.advance().value);
|
|
106
|
-
}
|
|
107
|
-
this.expect(lexer_1.TokenType.LBRACE);
|
|
108
|
-
// Parse properties (key: value)
|
|
109
|
-
const properties = {};
|
|
110
|
-
while (this.currentToken().type !== lexer_1.TokenType.RBRACE && this.currentToken().type !== lexer_1.TokenType.EOF) {
|
|
111
|
-
const key = this.expect(lexer_1.TokenType.IDENTIFIER).value;
|
|
112
|
-
this.expect(lexer_1.TokenType.COLON);
|
|
113
|
-
const value = this.parseValue();
|
|
114
|
-
properties[key] = value;
|
|
115
|
-
}
|
|
116
|
-
this.expect(lexer_1.TokenType.RBRACE);
|
|
117
|
-
return {
|
|
118
|
-
type: 'object',
|
|
119
|
-
name,
|
|
120
|
-
traits,
|
|
121
|
-
properties,
|
|
122
|
-
line: startToken.line,
|
|
123
|
-
column: startToken.column,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
parseValue() {
|
|
127
|
-
const token = this.currentToken();
|
|
128
|
-
// String value
|
|
129
|
-
if (token.type === lexer_1.TokenType.STRING) {
|
|
130
|
-
return this.advance().value;
|
|
131
|
-
}
|
|
132
|
-
// Number value
|
|
133
|
-
if (token.type === lexer_1.TokenType.NUMBER) {
|
|
134
|
-
return parseFloat(this.advance().value);
|
|
135
|
-
}
|
|
136
|
-
// Array value [1, 2, 3]
|
|
137
|
-
if (token.type === lexer_1.TokenType.LBRACKET) {
|
|
138
|
-
return this.parseArray();
|
|
139
|
-
}
|
|
140
|
-
// Function call (for future: diagonal([1, 2, 3]))
|
|
141
|
-
if (token.type === lexer_1.TokenType.IDENTIFIER && this.peek().type === lexer_1.TokenType.LBRACKET) {
|
|
142
|
-
this.advance(); // Skip function name for now
|
|
143
|
-
const args = this.parseArray();
|
|
144
|
-
// For now, treat function calls as arrays (e.g., diagonal([1,2,3]) -> [1,2,3])
|
|
145
|
-
// In future, could preserve function name metadata
|
|
146
|
-
return args;
|
|
147
|
-
}
|
|
148
|
-
throw new Error(`Unexpected value type ${token.type} "${token.value}" at line ${token.line}, column ${token.column}`);
|
|
149
|
-
}
|
|
150
|
-
parseArray() {
|
|
151
|
-
this.expect(lexer_1.TokenType.LBRACKET);
|
|
152
|
-
const values = [];
|
|
153
|
-
while (this.currentToken().type !== lexer_1.TokenType.RBRACKET && this.currentToken().type !== lexer_1.TokenType.EOF) {
|
|
154
|
-
if (this.currentToken().type === lexer_1.TokenType.NUMBER) {
|
|
155
|
-
values.push(parseFloat(this.advance().value));
|
|
156
|
-
}
|
|
157
|
-
else if (this.currentToken().type === lexer_1.TokenType.STRING) {
|
|
158
|
-
values.push(this.advance().value);
|
|
159
|
-
}
|
|
160
|
-
else if (this.currentToken().type === lexer_1.TokenType.LBRACKET) {
|
|
161
|
-
// Nested array
|
|
162
|
-
values.push(this.parseArray());
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
throw new Error(`Unexpected token in array: ${this.currentToken().type} at line ${this.currentToken().line}`);
|
|
166
|
-
}
|
|
167
|
-
// Optional comma
|
|
168
|
-
if (this.currentToken().type === lexer_1.TokenType.COMMA) {
|
|
169
|
-
this.advance();
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
this.expect(lexer_1.TokenType.RBRACKET);
|
|
173
|
-
return values;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
exports.Parser = Parser;
|
|
177
|
-
// Example usage
|
|
178
|
-
if (require.main === module) {
|
|
179
|
-
Promise.resolve().then(() => __importStar(require('./lexer'))).then(({ Lexer }) => {
|
|
180
|
-
const source = `
|
|
181
|
-
composition "TwoLinkArm" {
|
|
182
|
-
object "Base" @static {
|
|
183
|
-
geometry: "cylinder"
|
|
184
|
-
dimensions: [0.1, 0.05]
|
|
185
|
-
material: "metal"
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
object "Link1" @joint_revolute {
|
|
189
|
-
joint_axis: [0, 0, 1]
|
|
190
|
-
joint_limits: [-3.14, 3.14]
|
|
191
|
-
joint_effort: 100
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
`;
|
|
195
|
-
const lexer = new Lexer(source);
|
|
196
|
-
const tokens = lexer.tokenize();
|
|
197
|
-
const parser = new Parser(tokens);
|
|
198
|
-
const ast = parser.parse();
|
|
199
|
-
console.log('AST:');
|
|
200
|
-
console.log(JSON.stringify(ast, null, 2));
|
|
201
|
-
});
|
|
202
|
-
}
|
package/dist/usd-codegen.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HoloScript → USD Code Generator
|
|
3
|
-
*
|
|
4
|
-
* Generates Universal Scene Description (USD) files from HoloScript AST.
|
|
5
|
-
* Targets NVIDIA Isaac Sim with UsdPhysics schema.
|
|
6
|
-
*/
|
|
7
|
-
import { CompositionNode } from './ast';
|
|
8
|
-
export declare class USDCodeGen {
|
|
9
|
-
private output;
|
|
10
|
-
private indentLevel;
|
|
11
|
-
generate(ast: CompositionNode): string;
|
|
12
|
-
private generateLink;
|
|
13
|
-
private generateJoint;
|
|
14
|
-
private indent;
|
|
15
|
-
private emit;
|
|
16
|
-
private geometryToUSD;
|
|
17
|
-
private vectorToAxisName;
|
|
18
|
-
}
|