Skip to content

Commit f9b67b4

Browse files
committed
Add compiler support for charms
1 parent 142a371 commit f9b67b4

File tree

12 files changed

+460
-124
lines changed

12 files changed

+460
-124
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/target
22
Cargo.lock
3+
debug.log

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 4.0.0-alpha.18 (unreleased)
4+
5+
### New
6+
7+
### Changes
8+
9+
### Fixes
10+
311
## 4.0.0-alpha.17
412

513
### New

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rant"
3-
version = "4.0.0-alpha.17"
3+
version = "4.0.0-alpha.18"
44
authors = ["Berkin <[email protected]>"]
55
edition = "2018"
66
description = "The Rant procedural templating language"
@@ -20,7 +20,7 @@ include = [
2020
"!tests/unincluded_*.rs"
2121
]
2222
default-run = "rant"
23-
publish = false
23+
# publish = false
2424

2525
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
2626

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Rant's CLI can run Rant code from files or the command line.
8484
Install it from Cargo with:
8585

8686
```sh
87-
$ cargo install rant --version 4.0.0-alpha.17 --features cli
87+
$ cargo install rant --version 4.0.0-alpha.18 --features cli
8888
```
8989

9090
Then run it:

src/compiler.rs

+8
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ pub enum Problem {
130130
NestedFunctionDefMarkedConstant,
131131
ConstantReassignment(String),
132132
ConstantRedefinition(String),
133+
InvalidKeyword(String),
134+
WeightNotAllowed,
133135
FileNotFound(String),
134136
FileIOError(String),
135137
}
@@ -178,6 +180,10 @@ impl Problem {
178180
Problem::InvalidSink | Problem::InvalidSinkOn(_) => "R-0130",
179181
Problem::InvalidHint | Problem::InvalidHintOn(_) => "R-0131",
180182

183+
// Charms (0200 - 0249)
184+
Problem::InvalidKeyword(_) => "R-0200",
185+
Problem::WeightNotAllowed => "R-0201",
186+
181187
// Common warnings (1000 - 1099)
182188
Problem::UnusedVariable(_) => "R-1000",
183189
Problem::UnusedParameter(_) => "R-1001",
@@ -230,6 +236,8 @@ impl Problem {
230236
Problem::NothingToCompose => "no compose value is available in this scope".to_owned(),
231237
Problem::ConstantReassignment(cname) => format!("reassignment of known constant '{}'", cname),
232238
Problem::ConstantRedefinition(cname) => format!("redefinition of known constant '{}'", cname),
239+
Problem::InvalidKeyword(kw) => format!("invalid keyword: '@{}'", kw),
240+
Problem::WeightNotAllowed => "@weight is not allowed in this context".to_owned(),
233241
}
234242
}
235243

src/compiler/lexer.rs

+58-7
Original file line numberDiff line numberDiff line change
@@ -3,129 +3,174 @@ use crate::InternalString;
33

44
#[derive(Logos, Debug, PartialEq)]
55
pub enum RantToken {
6+
/// Sequence of printable non-whitespace characters
67
#[error]
78
#[regex(r"[\w\-_]+")]
89
Fragment,
10+
11+
/// Sequence of printable whitespace characters
12+
#[regex(r"\s+", filter_bs, priority = 2)]
13+
Whitespace,
14+
15+
/// Sequence of non-printable whitespace characters
16+
#[regex(r"[\r\n]+\s*|\s*[\r\n]+", logos::skip, priority = 3)]
17+
Blackspace,
918

19+
/// `{`
1020
#[token("{")]
1121
LeftBrace,
1222

23+
/// `|`
1324
#[token("|")]
1425
Pipe,
1526

27+
/// `}`
1628
#[token("}")]
1729
RightBrace,
1830

31+
/// `|>`
1932
#[token("|>")]
2033
Compose,
2134

35+
/// `[]`
2236
#[token("[]")]
2337
ComposeValue,
2438

39+
/// `<>`
2540
#[token("<>")]
2641
Defer,
2742

43+
/// `[`
2844
#[token("[")]
2945
LeftBracket,
3046

47+
/// `]`
3148
#[token("]")]
3249
RightBracket,
3350

51+
/// `(`
3452
#[token("(")]
3553
LeftParen,
3654

55+
/// `)`
3756
#[token(")")]
3857
RightParen,
3958

59+
/// `~`
4060
#[token("~")]
4161
EmptyValue,
4262

63+
/// `<`
4364
#[token("<")]
4465
LeftAngle,
4566

67+
/// `>`
4668
#[token(">")]
4769
RightAngle,
4870

71+
/// `:`
4972
#[token(":")]
5073
Colon,
5174

75+
/// `**`
5276
#[token("**")]
5377
Temporal,
5478

79+
/// Labeled temporal operator, e.g. `*a*`
5580
#[regex(r"\*[\w\d\-_]+\*", parse_temporal_spread_label)]
5681
TemporalLabeled(InternalString),
5782

83+
/// `*`
5884
#[token("*")]
5985
Star,
6086

87+
/// `+`
6188
#[token("+")]
6289
Plus,
6390

91+
/// `&`
6492
#[token("&")]
6593
And,
6694

95+
/// `=`
6796
#[token("=")]
6897
Equals,
6998

99+
/// `!`
70100
#[token("!")]
71101
Bang,
72102

103+
/// `?`
73104
#[token("?")]
74105
Question,
75106

107+
/// `;`
76108
#[token(";")]
77109
Semi,
78110

79-
#[token("@")]
111+
/// `@`
112+
#[token("@", priority = 1)]
80113
At,
114+
115+
/// Some charm keyword, e.g. `@return`
116+
#[regex(r"@[\w\d_-]+", parse_keyword, priority = 2, ignore(case))]
117+
Charm(InternalString),
81118

119+
/// `/`
82120
#[token("/")]
83121
Slash,
84122

123+
/// `^`
85124
#[token("^")]
86125
Caret,
87126

127+
/// `$`
88128
#[token("$")]
89129
Dollar,
90130

131+
/// `%`
91132
#[token("%")]
92133
Percent,
93134

135+
/// `'`
94136
#[token("'")]
95137
Hint,
96138

139+
/// `_`
97140
#[token("_")]
98141
Sink,
99142

143+
/// `true`
100144
#[token("true")]
101145
True,
102146

147+
/// `false`
103148
#[token("false")]
104149
False,
105150

106-
#[regex(r"\s+", filter_bs, priority = 2)]
107-
Whitespace,
108-
109-
#[regex(r"[\r\n]+\s*|\s*[\r\n]+", logos::skip, priority = 3)]
110-
Blackspace,
111-
151+
/// Integer literal
112152
#[regex(r"\-?[0-9]+", parse_integer, priority = 2)]
113153
Integer(i64),
114154

155+
/// Float literal
115156
#[regex(r"\-?[0-9]+\.[0-9]+", parse_float, priority = 3)]
116157
Float(f64),
117158

159+
/// Represents inline and multi-line comments
118160
#[regex(r"\s*##([^#]|#[^#])*(##\s*)?", logos::skip, priority = 6)]
119161
#[regex(r"\s*#([^#][^\r\n]*)?\n?", logos::skip, priority = 5)]
120162
Comment,
121163

164+
/// Represents any escape sequence
122165
#[regex(r"\\\S", parse_escape, priority = 10)]
123166
#[regex(r"\\x[0-9a-fA-F][0-9a-fA-F]", parse_code_point_escape, priority = 7)]
124167
Escape(char),
125168

169+
/// Represents a verbatim string literal, e.g. `"hello world"`
126170
#[regex(r#""(""|[^"])*""#, parse_string_literal)]
127171
StringLiteral(InternalString),
128172

173+
/// Error token indicating an unterminated string literal, e.g. `"foo`
129174
#[regex(r#""(""|[^"])*"#)]
130175
UnterminatedStringLiteral,
131176
}
@@ -158,6 +203,12 @@ fn parse_string_literal(lex: &mut Lexer<RantToken>) -> Option<InternalString> {
158203
Some(string_content)
159204
}
160205

206+
fn parse_keyword(lex: &mut Lexer<RantToken>) -> InternalString {
207+
let kwd_literal = lex.slice();
208+
let kwd_content = &kwd_literal[1..];
209+
InternalString::from(kwd_content)
210+
}
211+
161212
/// Filter function for whitespace lexer rule to exclude whitespace at start of source
162213
fn filter_bs(lex: &mut Lexer<RantToken>) -> Filter<()> {
163214
if lex.span().start > 0 {

0 commit comments

Comments
 (0)