2023-03-24 04:04:05 +00:00
|
|
|
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
2023-03-24 04:05:45 +00:00
|
|
|
|
2023-03-24 04:04:05 +00:00
|
|
|
export type ParsedFunctionoidDef = {
|
|
|
|
|
path: string,
|
|
|
|
|
name: string,
|
|
|
|
|
params?: {
|
|
|
|
|
name: string,
|
|
|
|
|
defaultValue: string,
|
|
|
|
|
}[],
|
|
|
|
|
signature: string,
|
|
|
|
|
referencesChildren: boolean | null,
|
|
|
|
|
};
|
|
|
|
|
export type ParsedFunctionoidDefs = {[name: string]: ParsedFunctionoidDef};
|
|
|
|
|
|
|
|
|
|
export type ParsedFile = {
|
|
|
|
|
functions: ParsedFunctionoidDefs,
|
|
|
|
|
modules: ParsedFunctionoidDefs,
|
|
|
|
|
vars: string[],
|
|
|
|
|
includes: string[],
|
|
|
|
|
uses: string[],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const stripComments = (src: string) => src.replaceAll(/\/\*(.|[\s\S])*?\*\/|\/\/.*?$/gm, '');
|
|
|
|
|
|
|
|
|
|
export function parseOpenSCAD(path: string, src: string, skipPrivates: boolean): ParsedFile {
|
|
|
|
|
const withoutComments = stripComments(src);
|
|
|
|
|
const vars = [];
|
|
|
|
|
const functions: ParsedFunctionoidDefs = {};
|
|
|
|
|
const modules: ParsedFunctionoidDefs = {};
|
|
|
|
|
const includes: string[] = [];
|
|
|
|
|
const uses: string[] = [];
|
|
|
|
|
for (const m of withoutComments.matchAll(/(use|include)\s*<([^>]+)>/g)) {
|
|
|
|
|
(m[1] == 'use' ? uses : includes).push(m[2]);
|
|
|
|
|
}
|
|
|
|
|
for (const m of withoutComments.matchAll(/(?:^|[{};])\s*([$\w]+)\s*=/g)) {
|
|
|
|
|
vars.push(m[1]);
|
|
|
|
|
}
|
|
|
|
|
for (const m of withoutComments.matchAll(/(function|module)\s+([$\w]+)\s*\(([^)]*)\)(?:\s*(?:=\s*)?(\{\}|[^{}]+?;))?/gm)) {
|
|
|
|
|
const type = m[1];
|
|
|
|
|
const name = m[2];
|
|
|
|
|
if (skipPrivates && name.startsWith('_')) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const paramsStr = m[3];
|
|
|
|
|
const optBody = m[4];
|
|
|
|
|
const params = [];
|
|
|
|
|
if (/^(\s*([$\w]+(\s*=[^,()[]+)?(\s*,\s*[$\w]+(\s*=[^,()[]+)?)*)?\s*)$/m.test(paramsStr)) {
|
|
|
|
|
for (const paramStr of paramsStr.split(',')) {
|
|
|
|
|
const am = /^\s*([$\w]+)(?:\s*=([^,()[]+))?\s*$/.exec(paramStr);
|
|
|
|
|
if (am) {
|
|
|
|
|
const paramName = am[1];
|
|
|
|
|
const defaultValue = am[2];
|
|
|
|
|
params.push({
|
|
|
|
|
name: paramName,
|
|
|
|
|
defaultValue
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
(type == 'function' ? functions : modules)[name] = {
|
|
|
|
|
path,
|
|
|
|
|
name,
|
|
|
|
|
signature: `${name}(${paramsStr.replaceAll(/[\s]+/gm, ' ').replaceAll(/\b | \b/g, '')})`,
|
|
|
|
|
params,
|
|
|
|
|
referencesChildren: optBody != null ? (optBody.indexOf('children()') >= 0) : null,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return {vars, functions, modules, includes, uses};
|
|
|
|
|
}
|