Skip to content

Commit 048f1b4

Browse files
vinay-veerappaDeusData
authored andcommitted
feat(lang): add Pine Script support via vendored kvarenzn/tree-sitter-pine (#273)
Adds Pine Script (TradingView's indicator/strategy DSL) as a first-class language using the project's existing language-add pipeline: - scripts/new-languages.json: register pine (display "PineScript", ts_func tree_sitter_pine, repo kvarenzn/tree-sitter-pine, extension .pine, has_scanner=true, module_root source_file) - internal/cbm/vendored/grammars/pine/: vendored from https://github.com/kvarenzn/tree-sitter-pine via scripts/vendor-grammar.sh — parser.c, scanner.c, tree_sitter/ headers. License is ISC (declared in upstream package.json; written into vendored LICENSE for clarity since upstream has no LICENSE file) - internal/cbm/grammar_pine.c: 4-line wrapper generated by scripts/generate-lang-code.py wrappers - internal/cbm/cbm.h: CBM_LANG_PINE before CBM_LANG_COUNT - internal/cbm/lang_specs.c: 7 node-type arrays (func / class / module / call / var / branch / assign) cross-checked against kvarenzn's grammar.js, plus the spec table entry - src/discover/language.c: .pine -> CBM_LANG_PINE extension dispatch and "PineScript" name scripts/audit-grammar-security.sh on the vendored grammar: no dangerous includes (only string/stdint/stdbool/stdlib), no system / popen / exec / socket / mmap / dlopen calls, no constructor/destructor attributes, no inline asm. The 148-line scanner.c only handles INDENT/DEDENT/NEWLINE tokens via the standard tree-sitter lexer API. Distilled from #273 rather than vendored verbatim because the original PR's parser.c was a plain 46k-line drop without provenance, no LICENSE attribution, and bundled an unrelated Makefile change (scripts/embed-frontend.sh -> sh scripts/embed-frontend.sh) that didn't belong to a Pine Script feature. The node-type choices in the lang spec match the original PR's selections, all of which were verified to be real grammar.js rules. Full suite: 2840 passed, 0 failed under ASan + UBSan. Closes #273. Co-authored-by: vinay-veerappa <vinay.veerappa@gmail.com>
1 parent 2b07bc0 commit 048f1b4

11 files changed

Lines changed: 48286 additions & 90 deletions

File tree

internal/cbm/cbm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ typedef enum {
166166
CBM_LANG_SOSL,
167167
CBM_LANG_KUSTOMIZE, // kustomization.yaml — Kubernetes overlay tool
168168
CBM_LANG_K8S, // Generic Kubernetes manifest (apiVersion: detected)
169+
CBM_LANG_PINE, // Pine Script (TradingView indicator / strategy language)
169170
CBM_LANG_COUNT
170171
} CBMLanguage;
171172

internal/cbm/grammar_pine.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Vendored tree-sitter grammar: pine
2+
// Each grammar compiled as separate unit (conflicting static symbols).
3+
#include "vendored/grammars/pine/parser.c"
4+
#include "vendored/grammars/pine/scanner.c"

internal/cbm/lang_specs.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ extern const TSLanguage *tree_sitter_gomod(void);
161161
extern const TSLanguage *tree_sitter_apex(void);
162162
extern const TSLanguage *tree_sitter_soql(void);
163163
extern const TSLanguage *tree_sitter_sosl(void);
164+
extern const TSLanguage *tree_sitter_pine(void);
164165

165166
// -- Empty sentinel --
166167
static const char *empty_types[] = {NULL};
@@ -1501,6 +1502,18 @@ static const char *sosl_module_types[] = {"source_file", NULL};
15011502

15021503
static const char *make_func_types[] = {"recipe", NULL};
15031504
static const char *make_import_types[] = {"include", "include_directive", NULL};
1505+
1506+
// ==================== PINE SCRIPT ====================
1507+
// Node names verified against kvarenzn/tree-sitter-pine grammar.js.
1508+
static const char *pine_func_types[] = {"function_declaration_statement", NULL};
1509+
static const char *pine_class_types[] = {"type_definition_statement", NULL};
1510+
static const char *pine_module_types[] = {"source_file", NULL};
1511+
static const char *pine_call_types[] = {"call", NULL};
1512+
static const char *pine_var_types[] = {"variable_definition_statement", "tuple_declaration_statement",
1513+
NULL};
1514+
static const char *pine_branch_types[] = {"if_statement", "switch_statement", "for_statement",
1515+
"for_in_statement", "while_statement", NULL};
1516+
static const char *pine_assign_types[] = {"reassignment_statement", NULL};
15041517
// ==================== SPEC TABLE ====================
15051518

15061519
static const CBMLangSpec lang_specs[CBM_LANG_COUNT] = {
@@ -2428,6 +2441,12 @@ static const CBMLangSpec lang_specs[CBM_LANG_COUNT] = {
24282441
empty_types, empty_types, empty_types, empty_types, empty_types, empty_types,
24292442
empty_types, NULL, empty_types, NULL, NULL, tree_sitter_yaml, NULL},
24302443

2444+
// CBM_LANG_PINE — Pine Script (TradingView). kvarenzn/tree-sitter-pine (ISC).
2445+
[CBM_LANG_PINE] = {CBM_LANG_PINE, pine_func_types, pine_class_types, empty_types,
2446+
pine_module_types, pine_call_types, empty_types, empty_types,
2447+
pine_branch_types, pine_var_types, pine_assign_types, empty_types, NULL,
2448+
empty_types, NULL, NULL, tree_sitter_pine, NULL},
2449+
24312450
};
24322451

24332452
_Static_assert(sizeof(lang_specs) / sizeof(lang_specs[0]) == CBM_LANG_COUNT,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Upstream: https://github.com/kvarenzn/tree-sitter-pine
2+
License declared in upstream package.json: ISC
3+
4+
ISC License
5+
6+
Copyright (c) kvarenzn
7+
8+
Permission to use, copy, modify, and/or distribute this software for any
9+
purpose with or without fee is hereby granted, provided that the above
10+
copyright notice and this permission notice appear in all copies.
11+
12+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

0 commit comments

Comments
 (0)