Compare commits

...

75 Commits

Author SHA1 Message Date
2f9590e006 Implement filter loop 2023-10-17 17:52:23 -04:00
6aab8e8f65 Implement transform loop 2023-10-17 16:39:54 -04:00
9fb89fcd8b Implement for loops 2023-10-17 13:46:10 -04:00
9ec43a9841 Implement length tool 2023-10-17 12:42:44 -04:00
cf22950b7e Add async statements 2023-10-16 21:13:39 -04:00
0f58ea5a7a Add async syntax 2023-10-16 16:47:43 -04:00
69778781ee Add async syntax 2023-10-16 16:36:07 -04:00
b47907ee26 Add more tools 2023-10-13 15:29:17 -04:00
7021c7f789 Add random tools 2023-10-13 13:52:49 -04:00
0b6c6b7e25 Add optional parentheses for expressions 2023-10-13 11:20:09 -04:00
c6ec1ff6ea Add assert and assert_equal tools 2023-10-11 12:07:21 -04:00
a207087cca Rename print to output 2023-10-10 15:50:57 -04:00
532c751c36 Implement new grammar 2023-10-09 14:39:47 -04:00
d7ff4e57c5 Implement function calls 2023-10-07 12:38:07 -04:00
3df0f5b37c Implement while loops 2023-10-06 22:51:04 -04:00
b55420d51b Begin implementing while loops 2023-10-06 22:45:27 -04:00
a3dbb19ecc Add tests; Improve parsing 2023-10-06 16:19:17 -04:00
03c5664851 Continue syntax overhaul 2023-10-06 13:32:49 -04:00
7398f073ed Continue syntax overhaul 2023-10-06 08:16:34 -04:00
405a2dc86c Continue syntax overhaul 2023-10-06 07:55:04 -04:00
dbe7991fc6 Continue syntax overhaul 2023-10-06 06:20:10 -04:00
4ddc656455 Revert "Restructure language grammar"
This reverts commit 6ed376335b.
2023-10-05 22:34:53 -04:00
6ed376335b Restructure language grammar 2023-10-05 22:26:44 -04:00
d0806c2694 Restructure language grammar 2023-10-05 22:05:18 -04:00
e09bc20198 Add tests; Fix string parsing 2023-10-05 16:49:03 -04:00
916b59b4b6 Make project a submodule of dust project 2023-10-05 09:24:54 -04:00
6902a301a6 Remove dust submodule 2023-10-05 09:06:54 -04:00
e6d83563ec Fix errors; Remove map keyword 2023-10-05 08:43:04 -04:00
0797a60677 Update syntax 2023-10-05 08:03:37 -04:00
bcc3557b77 Fix control flow 2023-10-02 18:54:49 -04:00
89a9f6ebb9 Implement lists 2023-10-02 15:20:00 -04:00
80f5fce14a Improve AST 2023-10-01 12:17:52 -04:00
63d495c1e1 Fix tests for new grammar 2023-10-01 06:09:29 -04:00
43432591b3 Implement assignment 2023-10-01 05:28:23 -04:00
c0c0b295ab Set license 2023-10-01 04:29:18 -04:00
24419e4fba Implement addition 2023-10-01 04:20:42 -04:00
8c05154e43 Fix tests for new grammar 2023-10-01 01:13:29 -04:00
17ba01c0dc Begin fixing tests for new grammar 2023-10-01 00:01:02 -04:00
57d908af9c Change syntax 2023-09-30 22:59:27 -04:00
69fda534a3 Change syntax 2023-09-30 21:12:35 -04:00
14c294a1db Implement function value 2023-09-30 17:53:01 -04:00
191970fabb Implement insert expression 2023-09-30 16:17:09 -04:00
77c15c5d54 Implement select expression 2023-09-30 16:06:01 -04:00
cbe92941a1 Fix identifier regex 2023-09-30 15:50:20 -04:00
d58c08125f Expand grammar 2023-09-30 15:47:21 -04:00
89e89f3433 Fix comment tests 2023-09-30 15:13:38 -04:00
0140193421 Sync modules 2023-09-29 17:58:28 -04:00
07340a4fe3 Add list tests 2023-09-29 17:19:23 -04:00
6774f83879 Add table tests 2023-09-29 16:54:13 -04:00
b0b4bfe59e Implement list 2023-09-29 16:34:20 -04:00
5a6c92372a Implement map syntax 2023-09-29 15:25:10 -04:00
0fa436832d Add syntax for functions and tables 2023-09-29 14:32:18 -04:00
9aef6712fe Remove semicolons from language 2023-09-29 13:04:19 -04:00
3c0ac94fdd Sync modules 2023-09-29 12:43:17 -04:00
4f9d97a12c Rearrange tests 2023-09-29 11:56:07 -04:00
424b1a42ef Fix tests 2023-09-29 09:53:53 -04:00
b4a114108b Add equality operator 2023-09-29 09:17:38 -04:00
20e6af2257 Add list support 2023-09-29 08:59:27 -04:00
f57570f14b Add float support; Write tests 2023-09-29 08:22:00 -04:00
954ea0928c Add new root node 2023-09-29 07:17:47 -04:00
c7bfba7767 Add tests and grammar for control flow 2023-09-29 03:52:21 -04:00
4b0c658a2b Add comment tests; Rewrite statment tests 2023-09-29 03:10:14 -04:00
b8384b936b Sync modules 2023-09-29 02:53:52 -04:00
faec13438e Implement closed and open statements 2023-09-29 00:17:16 -04:00
19e1316508 Sync modules 2023-09-28 23:30:23 -04:00
fdd841a2d2 Convert syntax tree to Evaluator 2023-09-28 22:55:47 -04:00
bbe1b96341 Continue build syntax and interpreter 2023-09-28 16:57:30 -04:00
e4d4640498 Update library 2023-09-28 15:58:31 -04:00
7c6a707d02 Implement basic tree sitter parsing 2023-09-28 15:56:32 -04:00
56be65a43c Add dust project as a submodule 2023-09-28 13:43:30 -04:00
dd857a8291 Add statment tests 2023-09-27 19:10:21 -04:00
ee5ba3bf3f Begin new grammar 2023-09-27 17:41:39 -04:00
07bd2dbdfa Merge 2023-09-25 09:00:27 -04:00
fbbeaf4a9e Update Cargo.lock 2023-09-22 06:48:32 -04:00
10564a0a6a Update grammar and tests 2023-09-22 06:38:25 -04:00
28 changed files with 12158 additions and 6519 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "bindings/dust"]
path = bindings/dust
url = ssh://git@git.jeffa.io:22022/jeff/dust.git

4877
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package] [package]
name = "tree-sitter-dust" name = "tree-sitter-dust"
description = "Dust grammar for the tree-sitter parsing library" description = "dust grammar for the tree-sitter parsing library"
version = "0.0.1" version = "0.0.1"
keywords = ["incremental", "parsing", "dust"] keywords = ["incremental", "parsing", "dust"]
categories = ["parsing", "text-editors"] categories = ["parsing", "text-editors"]
@ -8,7 +8,7 @@ repository = "https://github.com/tree-sitter/tree-sitter-dust"
edition = "2018" edition = "2018"
license = "MIT" license = "MIT"
build = "runtime/build.rs" build = "bindings/rust/build.rs"
include = [ include = [
"bindings/rust/*", "bindings/rust/*",
"grammar.js", "grammar.js",
@ -16,17 +16,11 @@ include = [
"src/*", "src/*",
] ]
[[bin]]
name = "main"
path = "runtime/main.rs"
[lib] [lib]
path = "runtime/lib.rs" path = "bindings/rust/lib.rs"
[dependencies] [dependencies]
clap = "4.4.4" rayon = "1.8.0"
dust-lang = "0.1.2"
rustyline = "12.0.0"
tree-sitter = "~0.20.10" tree-sitter = "~0.20.10"
[build-dependencies] [build-dependencies]

View File

@ -1,19 +0,0 @@
{
"targets": [
{
"target_name": "tree_sitter_Dust_binding",
"include_dirs": [
"<!(node -e \"require('nan')\")",
"src"
],
"sources": [
"bindings/node/binding.cc",
"src/parser.c",
# If your language uses an external scanner, add it here.
],
"cflags_c": [
"-std=c99",
]
}
]
}

169
corpus/async.txt Normal file
View File

@ -0,0 +1,169 @@
==================
Simple Async Statements
==================
async { (output 'Whaddup') }
---
(root
(item
(statement
(async
(statement
(expression
(function_call
(tool)
(expression
(value
(string))))))))))
==================
Complex Async Statements
==================
async {
if 1 % 2 == 0 {
(output 'true')
} else {
(output 'false')
}
(output 'foobar')
}
---
(root
(item
(statement
(async
(statement
(if_else
(if
(expression
(logic
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(value
(integer)))))
(logic_operator)
(expression
(value
(integer)))))
(statement
(expression
(function_call
(tool)
(expression
(value
(string)))))))
(else
(statement
(expression
(function_call
(tool)
(expression
(value
(string)))))))))
(statement
(expression
(function_call
(tool)
(expression
(value
(string))))))))))
==================
Simple Async Await Statements
==================
x = async {
1
}
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(async
(statement
(expression
(value
(integer))))))))))
==================
Complex Async Await Statements
==================
x = async {
i = 0
while i < 5 {
(output i)
i += 1
}
(read "examples/assets/faithful.csv")
}
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(async
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(value
(integer))))))
(statement
(while
(expression
(logic
(expression
(identifier))
(logic_operator)
(expression
(value
(integer)))))
(item
(statement
(expression
(function_call
(tool)
(expression
(identifier)))))
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(value
(integer)))))))))
(statement
(expression
(function_call
(tool)
(expression
(value
(string))))))))))))

34
corpus/comments.txt Normal file
View File

@ -0,0 +1,34 @@
==================
Full Line Comments
==================
not_a_comment
# comment
---
(root
(item
(statement
(expression
(identifier))))
(item
(statement
(comment))))
==================
Partial Line Comments
==================
not_a_comment # comment
---
(root
(item
(statement
(expression
(identifier))))
(item
(statement
(comment))))

178
corpus/control_flow.txt Normal file
View File

@ -0,0 +1,178 @@
==================
If
==================
if true { "True" }
---
(root
(item
(statement
(if_else
(if
(expression
(value
(boolean)))
(statement
(expression
(value
(string)))))))))
==================
If Assignment
==================
x = if true { 1 }
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(if_else
(if
(expression
(value
(boolean)))
(statement
(expression
(value
(integer)))))))))))
==================
If Else
==================
if false { "True" } else { "False" }
---
(root
(item
(statement
(if_else
(if
(expression
(value
(boolean)))
(statement
(expression
(value
(string)))))
(else
(statement
(expression
(value
(string)))))))))
==================
If Else If
==================
if 1 == 1 {
"math is fun"
} else if 4 == 9 {
"math is broken"
}
---
(root
(item
(statement
(if_else
(if
(expression
(logic
(expression
(value
(integer)))
(logic_operator)
(expression
(value
(integer)))))
(statement
(expression
(value
(string)))))
(else_if
(expression
(logic
(expression
(value
(integer)))
(logic_operator)
(expression
(value
(integer)))))
(statement
(expression
(value
(string)))))))))
==================
If Else Else If Else
==================
if false {
"no"
} else if false {
"no"
} else if 1 + 1 == 9 {
"not the answer"
} else {
"42"
}
---
(root
(item
(statement
(if_else
(if
(expression
(value
(boolean)))
(statement
(expression
(value
(string)))))
(else_if
(expression
(value
(boolean)))
(statement
(expression
(value
(string)))))
(else_if
(expression
(logic
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(value
(integer)))))
(logic_operator)
(expression
(value
(integer)))))
(statement
(expression
(value
(string)))))
(else
(statement
(expression
(value
(string)))))))))

79
corpus/filter.txt Normal file
View File

@ -0,0 +1,79 @@
==================
Filter Loop
==================
filter i in [1, 2, 3] {
i <= 1
}
---
(root
(item
(statement
(filter
(identifier)
(expression
(value
(list
(expression
(value
(integer)))
(expression
(value
(integer)))
(expression
(value
(integer))))))
(item
(statement
(expression
(logic
(expression
(identifier))
(logic_operator)
(expression
(value
(integer)))))))))))
==================
Filter Loop Assignment
==================
list = filter i in ["one", "two", "three"] {
i == "one"
}
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(filter
(identifier)
(expression
(value
(list
(expression
(value
(string)))
(expression
(value
(string)))
(expression
(value
(string))))))
(item
(statement
(expression
(logic
(expression
(identifier))
(logic_operator)
(expression
(value
(string)))))))))))))

92
corpus/for.txt Normal file
View File

@ -0,0 +1,92 @@
==================
Simple For Loop
==================
for i in [1, 2, 3] {
(output i)
}
---
(root
(item
(statement
(for
(identifier)
(expression
(value
(list
(expression
(value
(integer)))
(expression
(value
(integer)))
(expression
(value
(integer))))))
(item
(statement
(expression
(function_call
(tool)
(expression
(identifier))))))))))
==================
Complex For Loop
==================
for list in list_of_lists {
for item in list {
(output item)
}
if (length list) > 1 {
(output "List is long...")
}
}
---
(root
(item
(statement
(for
(identifier)
(expression
(identifier))
(item
(statement
(for
(identifier)
(expression
(identifier))
(item
(statement
(expression
(function_call
(tool)
(expression
(identifier))))))))
(statement
(if_else
(if
(expression
(logic
(expression
(function_call
(tool)
(expression
(identifier))))
(logic_operator)
(expression
(value
(integer)))))
(statement
(expression
(function_call
(tool)
(expression
(value
(string))))))))))))))

109
corpus/functions.txt Normal file
View File

@ -0,0 +1,109 @@
==================
Simple Function
==================
function { "Hiya" }
---
(root
(item
(statement
(expression
(value
(function
(item
(statement
(expression
(value
(string)))))))))))
==================
Function Call
==================
(foobar "Hiya")
---
(root
(item
(statement
(expression
(function_call
(identifier)
(expression
(value
(string))))))))
==================
Complex Function
==================
function <message number> {
(output message)
(output number)
}
---
(root
(item
(statement
(expression
(value
(function
(identifier)
(identifier)
(item
(statement
(expression
(function_call
(tool)
(expression
(identifier)))))
(statement
(expression
(function_call
(tool)
(expression
(identifier))))))))))))
==================
Complex Function Call
==================
(foobar
"hi"
42
{
x = 1
y = 2
}
)
---
(root
(item
(statement
(expression
(function_call
(identifier)
(expression
(value
(string)))
(expression
(value
(integer)))
(expression
(value
(map
(identifier)
(expression
(value
(integer)))
(identifier)
(expression
(value
(integer)))))))))))

72
corpus/lists.txt Normal file
View File

@ -0,0 +1,72 @@
==================
List Declaration
==================
['answer', 42]
---
(root
(item
(statement
(expression
(value
(list
(expression
(value
(string)))
(expression
(value
(integer)))))))))
==================
List Assignment
==================
foobar = ['foobar']
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(value
(list
(expression
(value
(string)))))))))))
==================
List Nesting
==================
['answers', [42, [666]]]
---
(root
(item
(statement
(expression
(value
(list
(expression
(value
(string)))
(expression
(value
(list
(expression
(value
(integer)))
(expression
(value
(list
(expression
(value
(integer)))))))))))))))

59
corpus/maps.txt Normal file
View File

@ -0,0 +1,59 @@
==================
Simple Map
==================
{
answer = 42
}
---
(root
(item
(statement
(expression
(value
(map
(identifier)
(expression
(value
(integer)))))))))
==================
Map Assignment
==================
x = {
answer = 42
}
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(value
(map
(identifier)
(expression
(value
(integer)))))))))))
==================
Map Access
==================
x.answer
---
(root
(item
(statement
(expression
(identifier)))))

98
corpus/operators.txt Normal file
View File

@ -0,0 +1,98 @@
==================
Equality
==================
3 == 1 + 1 + 1
---
(root
(item
(statement
(expression
(logic
(expression
(value
(integer)))
(logic_operator)
(expression
(math
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(value
(integer)))))
(math_operator)
(expression
(value
(integer))))))))))
==================
&&
==================
4 + 2 == 42 && true
---
(root
(item
(statement
(expression
(logic
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(value
(integer)))))
(logic_operator)
(expression
(logic
(expression
(value
(integer)))
(logic_operator)
(expression
(value
(boolean))))))))))
==================
\||
==================
4 + 2 == 42 || true
---
(root
(item
(statement
(expression
(logic
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(value
(integer)))))
(logic_operator)
(expression
(logic
(expression
(value
(integer)))
(logic_operator)
(expression
(value
(boolean))))))))))

91
corpus/simple_values.txt Normal file
View File

@ -0,0 +1,91 @@
==================
Booleans
==================
true
false
---
(root
(item
(statement
(expression
(value
(boolean)))))
(item
(statement
(expression
(value
(boolean))))))
==================
Integers
==================
1 2 3
456 7
---
(root
(item
(statement
(expression
(value
(integer)))))
(item
(statement
(expression
(value
(integer)))))
(item
(statement
(expression
(value
(integer)))))
(item
(statement
(expression
(value
(integer)))))
(item
(statement
(expression
(value
(integer))))))
==================
Strings
==================
"one" 'two' "three" `four` 'five'
---
(root
(item
(statement
(expression
(value
(string)))))
(item
(statement
(expression
(value
(string)))))
(item
(statement
(expression
(value
(string)))))
(item
(statement
(expression
(value
(string)))))
(item
(statement
(expression
(value
(string))))))

116
corpus/statements.txt Normal file
View File

@ -0,0 +1,116 @@
==================
Simple Statements
==================
1
"one"
x
---
(root
(item
(statement
(expression
(value
(integer)))))
(item
(statement
(expression
(value
(string)))))
(item
(statement
(expression
(identifier)))))
==================
Simple Assignment
==================
x = 1
y = "one"
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(value
(integer)))))))
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(value
(string))))))))
==================
Complex Assignment
==================
x = 1 + 1
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(value
(integer))))))))))
==================
Expression Precedence
==================
x = (3 == (1 + (2 + 2)))
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(logic
(expression
(value
(integer)))
(logic_operator)
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(value
(integer))))))))))))))

104
corpus/tables.txt Normal file
View File

@ -0,0 +1,104 @@
==================
Table Declaration
==================
table <text, number> {
['answer', 42]
}
---
(root
(item
(statement
(expression
(value
(table
(identifier)
(identifier)
(expression
(value
(list
(expression
(value
(string)))
(expression
(value
(integer))))))))))))
==================
Table Assignment
==================
foobar = table <text, number> {
['answer', 42]
}
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(value
(table
(identifier)
(identifier)
(expression
(value
(list
(expression
(value
(string)))
(expression
(value
(integer))))))))))))))
==================
Table Access
==================
select number from foobar where text == 'answer'
---
(root
(item
(statement
(select
(identifier)
(identifier)
(expression
(logic
(expression
(identifier))
(logic_operator)
(expression
(value
(string)))))))))
==================
Table Insert
==================
insert ['bob was here', 0] into foobar
---
(root
(item
(statement
(insert
(list
(expression
(value
(string)))
(expression
(value
(integer))))
(identifier)))))

View File

@ -1,182 +0,0 @@
==================
Comments
==================
# x = 1;
# unassigned_variable
x # xyz
---
(source_file
(comment)
(comment)
(expression
(identifier))
(comment))
==================
Identifiers
==================
variable_name
_unused_variable
__strange_format__
a
blahblah
x.x
---
(source_file
(expression
(identifier))
(expression
(identifier))
(expression
(identifier))
(expression
(identifier))
(expression
(identifier))
(expression
(identifier)))
==================
Operators
==================
x = y + y;
---
(source_file
(expression
(identifier)
(operator)
(expression
(identifier)
(operator)
(expression
(identifier))))
(chain))
==================
String
==================
"string"
---
(source_file
(expression
(value
(string))))
==================
Integer
==================
1
---
(source_file
(expression
(value
(integer))))
==================
Float
==================
1.0
---
(source_file
(expression
(value
(float))))
==================
List
==================
(1, 2)
---
(source_file
(expression
(value
(list
(expression
(value
(integer)))
(expression
(value
(integer)))))))
==================
Empty
==================
()
---
(source_file
(expression
(value
(empty))))
==================
Tool
==================
random_boolean();
---
(source_file
(expression
(tool))
(expression
(value
(empty)))
(chain))
==================
Boolean
==================
true false
---
(source_file
(expression
(value
(boolean)))
(expression
(value
(boolean))))
==================
Function
==================
{ output "hi" }
---
(source_file
(expression
(value
(boolean)))
(expression
(value
(boolean))))

73
corpus/transform.txt Normal file
View File

@ -0,0 +1,73 @@
==================
Transform Loop
==================
transform i in [1, 2, 3] {
(output i)
}
---
(root
(item
(statement
(transform
(identifier)
(expression
(value
(list
(expression
(value
(integer)))
(expression
(value
(integer)))
(expression
(value
(integer))))))
(item
(statement
(expression
(function_call
(tool)
(expression
(identifier))))))))))
==================
Transform Loop Assignment
==================
list = transform i in ["one", "two", "three"] {
(output i)
}
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(transform
(identifier)
(expression
(value
(list
(expression
(value
(string)))
(expression
(value
(string)))
(expression
(value
(string))))))
(item
(statement
(expression
(function_call
(tool)
(expression
(identifier))))))))))))

52
corpus/while.txt Normal file
View File

@ -0,0 +1,52 @@
==================
While Loop
==================
while true {
(output "This is a bad idea...")
}
---
(root
(item
(statement
(while
(expression
(value
(boolean)))
(item
(statement
(expression
(function_call
(tool)
(expression
(value
(string)))))))))))
==================
While Loop Assignment
==================
answer = while false {
42
}
---
(root
(item
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(while
(expression
(value
(boolean)))
(item
(statement
(expression
(value
(integer)))))))))))

View File

@ -1,6 +0,0 @@
# Comment
(1, 2, 3);
random_integer();
true;
false;

View File

@ -1,78 +1,269 @@
module.exports = grammar({ module.exports = grammar({
name: 'dust', name: 'dust',
word: $ => $.identifier,
rules: { rules: {
source_file: $ => repeat(choice( root: $ => repeat1($.item),
item: $ => prec.left(repeat1($.statement)),
statement: $ => choice(
$.comment, $.comment,
$.assignment,
$.expression, $.expression,
$.yield, $.if_else,
$.chain $.insert,
)), $.select,
$.while,
$.async,
$.for,
$.transform,
$.filter,
),
comment: $ => seq(/[#]+.*/),
expression: $ => choice( expression: $ => choice(
prec(2, $.value), $._expression_kind,
prec(1, $.identifier), seq('(', $._expression_kind, ')'),
$.tool,
seq($.identifier, $.operator, $.expression),
), ),
_expression_kind: $ => prec.right(choice(
$.value,
$.identifier,
$.function_call,
$.math,
$.logic,
)),
identifier: $ => /[a-z|_|.]+[0-9]?/,
value: $ => choice( value: $ => choice(
$.integer, $.integer,
$.float, $.float,
$.string, $.string,
$.list,
$.empty,
$.boolean, $.boolean,
$.list,
$.function,
$.table,
$.map,
), ),
comment: $ => /(#)(.+?)([\n\r])/, integer: $ => /[-]?[0-9]+/,
yield: $ => "->", float: $ => /[-]?[0-9]+[.]{1}[0-9]*/,
chain: $ => ";", string: $ => /("[^"]*?")|('[^']*?')|(`[^`]*?`)/,
identifier: $ => /[a-zA-Z|_|.]+(_[a-zA-Z]+)*/,
operator: $ => choice(
'=',
'-',
'+',
'/',
'|',
'&'
),
tool: $ => choice(
"random",
"random_boolean",
"random_integer",
"random_string",
"random_float"
),
float: $ => /\d+\.\d*/,
integer: $ => /\d+/,
string: $ => seq(
'"',
repeat(),
'"'
),
function: $ => /\{(.*?)\}/,
empty: $ => "()",
boolean: $ => choice( boolean: $ => choice(
"true", 'true',
"false" 'false',
), ),
list: $ => seq( list: $ => seq(
'[',
repeat(seq($.expression, optional(','))),
']'
),
function: $ => seq(
'function',
optional(seq('<', repeat(seq($.identifier, optional(','))), '>')),
'{',
$.item,
'}',
),
table: $ => seq(
'table',
seq('<', repeat1(seq($.identifier, optional(','))), '>'),
'{',
repeat($.expression),
'}',
),
map: $ => seq(
'{',
repeat(seq($.identifier, "=", $.expression)),
'}',
),
math: $ => prec.left(seq(
$.expression,
$.math_operator,
$.expression,
)),
math_operator: $ => choice(
'+',
'-',
'*',
'/',
'%',
),
logic: $ => prec.right(seq(
$.expression,
$.logic_operator,
$.expression,
)),
logic_operator: $ => choice(
'==',
'!=',
'&&',
'||',
'>',
'<',
">=",
"<=",
),
assignment: $ => prec.right(seq(
$.identifier,
$.assignment_operator,
$.statement,
)),
assignment_operator: $ => choice(
"=",
"+=",
"-=",
),
if_else: $ => prec.left(seq(
$.if,
repeat(seq($.else_if)),
optional(seq($.else)),
)),
if: $ => seq(
'if',
$.expression,
'{',
$.statement,
'}',
),
else_if: $ => seq(
'else if',
$.expression,
'{',
$.statement,
'}',
),
else: $ => seq(
'else',
'{',
$.statement,
'}',
),
function_call: $ => prec.right(seq(
'(', '(',
repeat1(seq($.expression, optional(','))), choice($.identifier, $.tool),
')' repeat(seq($.expression, optional(','))),
')',
)),
while: $ => seq(
'while',
$.expression,
'{',
$.item,
'}',
),
for: $ => seq(
'for',
$.identifier,
'in',
$.expression,
'{',
$.item,
'}',
),
transform: $ => seq(
'transform',
$.identifier,
'in',
$.expression,
'{',
$.item,
'}',
),
filter: $ => seq(
'filter',
$.identifier,
'in',
$.expression,
'{',
$.item,
'}',
),
tool: $ => choice(
'assert',
'assert_equal',
'output',
'read',
'write',
'raw',
'sh',
'bash',
'fish',
'zsh',
'random',
'random_boolean',
'random_float',
'random_string',
'random_integer',
'length',
'sort',
'transform',
'filter',
'to_csv',
'from_csv',
'to_json',
'from_json',
'help',
),
select: $ => prec.right(seq(
'select',
$.identifier,
'from',
$.identifier,
optional(
seq('where', $.expression)
),
)),
insert: $ => prec.right(seq(
'insert',
repeat1($.list),
'into',
$.identifier,
optional(
seq('where', $.logic)
),
)),
async: $ => seq(
'async',
'{',
repeat($.statement),
'}'
), ),
} }
}); });

View File

@ -2,12 +2,8 @@
"name": "tree-sitter-dust", "name": "tree-sitter-dust",
"version": "1.0.0", "version": "1.0.0",
"description": "Tree Sitter grammar for the Dust programming language", "description": "Tree Sitter grammar for the Dust programming language",
"main": "bindings/node",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Jeff Anderson", "author": "Jeff Anderson",
"license": "ISC", "license": "MIT",
"tree-sitter": [ "tree-sitter": [
{ {
"scope": "source.dust", "scope": "source.dust",
@ -23,5 +19,6 @@
}, },
"devDependencies": { "devDependencies": {
"tree-sitter-cli": "^0.20.8" "tree-sitter-cli": "^0.20.8"
} },
"main": "bindings/node"
} }

View File

@ -1,40 +0,0 @@
fn main() {
let src_dir = std::path::Path::new("src");
let mut c_config = cc::Build::new();
c_config.include(&src_dir);
c_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable")
.flag_if_supported("-Wno-trigraphs");
let parser_path = src_dir.join("parser.c");
c_config.file(&parser_path);
// If your language uses an external scanner written in C,
// then include this block of code:
/*
let scanner_path = src_dir.join("scanner.c");
c_config.file(&scanner_path);
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
*/
c_config.compile("parser");
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
// If your language uses an external scanner written in C++,
// then include this block of code:
/*
let mut cpp_config = cc::Build::new();
cpp_config.cpp(true);
cpp_config.include(&src_dir);
cpp_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable");
let scanner_path = src_dir.join("scanner.cc");
cpp_config.file(&scanner_path);
cpp_config.compile("scanner");
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
*/
}

View File

@ -1,68 +0,0 @@
//! This crate provides Dust language support for the [tree-sitter][] parsing library.
//!
//! Typically, you will use the [language][language func] function to add this language to a
//! tree-sitter [Parser][], and then use the parser to parse some code:
//!
//! ```
//! let code = "";
//! let mut parser = tree_sitter::Parser::new();
//! parser.set_language(tree_sitter_Dust::language()).expect("Error loading Dust grammar");
//! let tree = parser.parse(code, None).unwrap();
//! ```
//!
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
//! [language func]: fn.language.html
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
//! [tree-sitter]: https://tree-sitter.github.io/
use tree_sitter::{Language, Node};
use dust_lib::Value;
extern "C" {
fn tree_sitter_dust() -> Language;
}
/// Get the tree-sitter [Language][] for this grammar.
///
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
pub fn language() -> Language {
unsafe { tree_sitter_dust() }
}
/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &'static str = include_str!("../src/node-types.json");
pub fn evaluate(root: Node) -> Value {
let cursor = root.walk();
if let Some(name) = cursor.field_name() {
match name {
"source" => Value::Empty,
_ => Value::Empty,
}
}
}
// Uncomment these to include any queries that this grammar contains
// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
#[cfg(test)]
mod tests {
#[test]
fn test_can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
parser
.set_language(super::language())
.expect("Error loading Dust language");
}
}

View File

@ -1,38 +0,0 @@
//! Command line interface for the dust programming language.
use clap::Parser;
use std::fs::read_to_string;
use tree_sitter::{Parser as TSParser, Language};
/// Command-line arguments to be parsed.
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Whale source code to evaluate.
#[arg(short, long)]
command: Option<String>,
/// Location of the file to run.
path: Option<String>,
}
fn main() {
let args = Args::parse();
if args.path.is_none() && args.command.is_none() {
todo!();
}
if let Some(path) = args.path {
let file_contents = read_to_string(path).unwrap();
let mut parser = TSParser::new();
parser.set_language(tree_sitter_dust::language()).unwrap();
let tree = parser.parse(&file_contents, None).unwrap();
let root = tree.root_node();
tree_sitter_dust::evaluate(root);
println!("{tree:?}");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,124 @@
[ [
{
"type": "assignment",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "assignment_operator",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "statement",
"named": true
}
]
}
},
{
"type": "assignment_operator",
"named": true,
"fields": {}
},
{
"type": "async",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "statement",
"named": true
}
]
}
},
{ {
"type": "boolean", "type": "boolean",
"named": true, "named": true,
"fields": {} "fields": {}
}, },
{
"type": "comment",
"named": true,
"fields": {}
},
{
"type": "else",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "statement",
"named": true
}
]
}
},
{
"type": "else_if",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{ {
"type": "expression", "type": "expression",
"named": true
},
{
"type": "statement",
"named": true
}
]
}
},
{
"type": "expression",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "function_call",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "logic",
"named": true
},
{
"type": "math",
"named": true
},
{
"type": "value",
"named": true
}
]
}
},
{
"type": "filter",
"named": true, "named": true,
"fields": {}, "fields": {},
"children": { "children": {
@ -21,15 +134,152 @@
"named": true "named": true
}, },
{ {
"type": "operator", "type": "item",
"named": true
}
]
}
},
{
"type": "for",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "item",
"named": true
}
]
}
},
{
"type": "function",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "identifier",
"named": true
},
{
"type": "item",
"named": true
}
]
}
},
{
"type": "function_call",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "identifier",
"named": true "named": true
}, },
{ {
"type": "tool", "type": "tool",
"named": true "named": true
}
]
}
}, },
{ {
"type": "value", "type": "if",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "statement",
"named": true
}
]
}
},
{
"type": "if_else",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "else",
"named": true
},
{
"type": "else_if",
"named": true
},
{
"type": "if",
"named": true
}
]
}
},
{
"type": "insert",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "identifier",
"named": true
},
{
"type": "list",
"named": true
},
{
"type": "logic",
"named": true
}
]
}
},
{
"type": "item",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "statement",
"named": true "named": true
} }
] ]
@ -41,7 +291,7 @@
"fields": {}, "fields": {},
"children": { "children": {
"multiple": true, "multiple": true,
"required": true, "required": false,
"types": [ "types": [
{ {
"type": "expression", "type": "expression",
@ -51,12 +301,31 @@
} }
}, },
{ {
"type": "operator", "type": "logic",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "logic_operator",
"named": true
}
]
}
},
{
"type": "logic_operator",
"named": true, "named": true,
"fields": {} "fields": {}
}, },
{ {
"type": "source_file", "type": "map",
"named": true, "named": true,
"fields": {}, "fields": {},
"children": { "children": {
@ -64,7 +333,88 @@
"required": false, "required": false,
"types": [ "types": [
{ {
"type": "chain", "type": "expression",
"named": true
},
{
"type": "identifier",
"named": true
}
]
}
},
{
"type": "math",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "math_operator",
"named": true
}
]
}
},
{
"type": "math_operator",
"named": true,
"fields": {}
},
{
"type": "root",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "item",
"named": true
}
]
}
},
{
"type": "select",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "identifier",
"named": true
}
]
}
},
{
"type": "statement",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "assignment",
"named": true
},
{
"type": "async",
"named": true "named": true
}, },
{ {
@ -76,7 +426,50 @@
"named": true "named": true
}, },
{ {
"type": "yield", "type": "filter",
"named": true
},
{
"type": "for",
"named": true
},
{
"type": "if_else",
"named": true
},
{
"type": "insert",
"named": true
},
{
"type": "select",
"named": true
},
{
"type": "transform",
"named": true
},
{
"type": "while",
"named": true
}
]
}
},
{
"type": "table",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "identifier",
"named": true "named": true
} }
] ]
@ -87,6 +480,29 @@
"named": true, "named": true,
"fields": {} "fields": {}
}, },
{
"type": "transform",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "item",
"named": true
}
]
}
},
{ {
"type": "value", "type": "value",
"named": true, "named": true,
@ -100,11 +516,11 @@
"named": true "named": true
}, },
{ {
"type": "empty", "type": "float",
"named": true "named": true
}, },
{ {
"type": "float", "type": "function",
"named": true "named": true
}, },
{ {
@ -115,15 +531,50 @@
"type": "list", "type": "list",
"named": true "named": true
}, },
{
"type": "map",
"named": true
},
{ {
"type": "string", "type": "string",
"named": true "named": true
},
{
"type": "table",
"named": true
} }
] ]
} }
}, },
{ {
"type": "&", "type": "while",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "item",
"named": true
}
]
}
},
{
"type": "!=",
"named": false
},
{
"type": "%",
"named": false
},
{
"type": "&&",
"named": false "named": false
}, },
{ {
@ -134,10 +585,18 @@
"type": ")", "type": ")",
"named": false "named": false
}, },
{
"type": "*",
"named": false
},
{ {
"type": "+", "type": "+",
"named": false "named": false
}, },
{
"type": "+=",
"named": false
},
{ {
"type": ",", "type": ",",
"named": false "named": false
@ -146,42 +605,142 @@
"type": "-", "type": "-",
"named": false "named": false
}, },
{
"type": "-=",
"named": false
},
{ {
"type": "/", "type": "/",
"named": false "named": false
}, },
{
"type": "<",
"named": false
},
{
"type": "<=",
"named": false
},
{ {
"type": "=", "type": "=",
"named": false "named": false
}, },
{ {
"type": "chain", "type": "==",
"named": true "named": false
}, },
{ {
"type": "comment", "type": ">",
"named": true "named": false
}, },
{ {
"type": "empty", "type": ">=",
"named": true "named": false
},
{
"type": "[",
"named": false
},
{
"type": "]",
"named": false
},
{
"type": "assert",
"named": false
},
{
"type": "assert_equal",
"named": false
},
{
"type": "async",
"named": false
},
{
"type": "bash",
"named": false
},
{
"type": "else",
"named": false
},
{
"type": "else if",
"named": false
}, },
{ {
"type": "false", "type": "false",
"named": false "named": false
}, },
{
"type": "filter",
"named": false
},
{
"type": "fish",
"named": false
},
{ {
"type": "float", "type": "float",
"named": true "named": true
}, },
{
"type": "for",
"named": false
},
{
"type": "from",
"named": false
},
{
"type": "from_csv",
"named": false
},
{
"type": "from_json",
"named": false
},
{
"type": "function",
"named": false
},
{
"type": "help",
"named": false
},
{ {
"type": "identifier", "type": "identifier",
"named": true "named": true
}, },
{
"type": "if",
"named": false
},
{
"type": "in",
"named": false
},
{
"type": "insert",
"named": false
},
{ {
"type": "integer", "type": "integer",
"named": true "named": true
}, },
{
"type": "into",
"named": false
},
{
"type": "length",
"named": false
},
{
"type": "output",
"named": false
},
{ {
"type": "random", "type": "random",
"named": false "named": false
@ -202,20 +761,76 @@
"type": "random_string", "type": "random_string",
"named": false "named": false
}, },
{
"type": "raw",
"named": false
},
{
"type": "read",
"named": false
},
{
"type": "select",
"named": false
},
{
"type": "sh",
"named": false
},
{
"type": "sort",
"named": false
},
{ {
"type": "string", "type": "string",
"named": true "named": true
}, },
{
"type": "table",
"named": false
},
{
"type": "to_csv",
"named": false
},
{
"type": "to_json",
"named": false
},
{
"type": "transform",
"named": false
},
{ {
"type": "true", "type": "true",
"named": false "named": false
}, },
{ {
"type": "yield", "type": "where",
"named": true "named": false
}, },
{ {
"type": "|", "type": "while",
"named": false
},
{
"type": "write",
"named": false
},
{
"type": "zsh",
"named": false
},
{
"type": "{",
"named": false
},
{
"type": "||",
"named": false
},
{
"type": "}",
"named": false "named": false
} }
] ]

10070
src/parser.c

File diff suppressed because it is too large Load Diff