mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 04:24:43 +00:00
Merge branch 'main' into beta
This commit is contained in:
commit
a9d4e5982b
8 changed files with 107 additions and 19 deletions
2
TODO.md
2
TODO.md
|
@ -135,4 +135,4 @@
|
|||
* [ ] Write educational materials to learn Erg while creating applications (e.g. CLI chess game -> GUI chess game, calculator -> toy language)
|
||||
* [ ] Develop Dyne (CPython compatible VM)
|
||||
* [ ] Develop Kayser (WebAssembly backend)
|
||||
* [ ] Develop Barye (LLVM backend)
|
||||
* [ ] Develop Gal (LLVM backend)
|
||||
|
|
|
@ -1330,13 +1330,13 @@ impl Context {
|
|||
proc.register_superclass(Obj, &obj);
|
||||
// TODO: lambda
|
||||
proc.register_marker_trait(mono("Named"));
|
||||
let mut func = Self::mono_class("Function", Self::TOP_LEVEL);
|
||||
func.register_superclass(mono("Procedure"), &proc);
|
||||
let mut func = Self::mono_class("Func", Self::TOP_LEVEL);
|
||||
func.register_superclass(mono("Proc"), &proc);
|
||||
func.register_superclass(Obj, &obj);
|
||||
// TODO: lambda
|
||||
func.register_marker_trait(mono("Named"));
|
||||
let mut qfunc = Self::mono_class("QuantifiedFunction", Self::TOP_LEVEL);
|
||||
qfunc.register_superclass(mono("Function"), &func);
|
||||
let mut qfunc = Self::mono_class("QuantifiedFunc", Self::TOP_LEVEL);
|
||||
qfunc.register_superclass(mono("Func"), &func);
|
||||
qfunc.register_superclass(Obj, &obj);
|
||||
self.register_builtin_type(Obj, obj, Const);
|
||||
// self.register_type(mono("Record"), vec![], record, Const);
|
||||
|
@ -1423,9 +1423,9 @@ impl Context {
|
|||
self.register_builtin_type(array_mut_t, array_mut_, Const);
|
||||
self.register_builtin_type(range_t, range, Const);
|
||||
self.register_builtin_type(mono("Tuple"), tuple_, Const);
|
||||
self.register_builtin_type(mono("Procedure"), proc, Const);
|
||||
self.register_builtin_type(mono("Function"), func, Const);
|
||||
self.register_builtin_type(mono("QuantifiedFunction"), qfunc, Const);
|
||||
self.register_builtin_type(mono("Proc"), proc, Const);
|
||||
self.register_builtin_type(mono("Func"), func, Const);
|
||||
self.register_builtin_type(mono("QuantifiedFunc"), qfunc, Const);
|
||||
}
|
||||
|
||||
fn init_builtin_funcs(&mut self) {
|
||||
|
|
|
@ -1089,13 +1089,13 @@ impl Context {
|
|||
}
|
||||
}
|
||||
Type::Quantified(_) => {
|
||||
if let Some(res) = self.get_nominal_type_ctx(&mono("QuantifiedFunction")) {
|
||||
if let Some(res) = self.get_nominal_type_ctx(&mono("QuantifiedFunc")) {
|
||||
return Some(res);
|
||||
}
|
||||
}
|
||||
Type::Subr(_subr) => match _subr.kind {
|
||||
SubrKind::Func => {
|
||||
if let Some(res) = self.get_nominal_type_ctx(&mono("Function")) {
|
||||
if let Some(res) = self.get_nominal_type_ctx(&mono("Func")) {
|
||||
return Some(res);
|
||||
}
|
||||
}
|
||||
|
@ -1157,7 +1157,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
Type::Quantified(_) => {
|
||||
if let Some(res) = self.get_mut_nominal_type_ctx(&mono("QuantifiedFunction")) {
|
||||
if let Some(res) = self.get_mut_nominal_type_ctx(&mono("QuantifiedFunc")) {
|
||||
return Some(res);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -285,6 +285,62 @@ impl Lexer /*<'a>*/ {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn lex_multi_line_comment(&mut self) -> LexResult<()> {
|
||||
let mut s = "".to_string();
|
||||
let mut nest_level = 0;
|
||||
loop {
|
||||
match self.peek_cur_ch() {
|
||||
Some(c) => {
|
||||
if let Some(next_c) = self.peek_next_ch() {
|
||||
match (c, next_c) {
|
||||
('#', '[') => nest_level += 1,
|
||||
(']', '#') => {
|
||||
nest_level -= 1;
|
||||
if nest_level == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if c == '\n' {
|
||||
self.lineno_token_starts += 1;
|
||||
self.col_token_starts = 0;
|
||||
}
|
||||
s.push(self.consume().unwrap());
|
||||
}
|
||||
if Self::is_bidi(self.peek_cur_ch().unwrap()) {
|
||||
let comment = self.emit_token(Illegal, &s);
|
||||
return Err(LexError::syntax_error(
|
||||
0,
|
||||
comment.loc(),
|
||||
switch_lang!(
|
||||
"japanese" => "不正なユニコード文字(双方向オーバーライド)がコメント中に使用されています",
|
||||
"simplified_chinese" => "注释中使用了非法的unicode字符(双向覆盖)",
|
||||
"traditional_chinese" => "註釋中使用了非法的unicode字符(雙向覆蓋)",
|
||||
"english" => "invalid unicode character (bi-directional override) in comments",
|
||||
),
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let comment = self.emit_token(Illegal, &s);
|
||||
return Err(LexError::syntax_error(
|
||||
0,
|
||||
comment.loc(),
|
||||
switch_lang!(
|
||||
"japanese" => "複数行コメントが]#で閉じられていません",
|
||||
"simplified_chinese" => "未用]#号结束的多处评论",
|
||||
"traditional_chinese" => "多條評論未用]#關閉",
|
||||
"english" => "Multi-comment is not closed with ]#",
|
||||
),
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lex_space_indent_dedent(&mut self) -> Option<LexResult<Token>> {
|
||||
let is_toplevel = self.cursor > 0
|
||||
&& !self.indent_stack.is_empty()
|
||||
|
@ -349,6 +405,11 @@ impl Lexer /*<'a>*/ {
|
|||
}
|
||||
// ignore indents if the current line is a comment
|
||||
if let Some('#') = self.peek_cur_ch() {
|
||||
if let Some('[') = self.peek_next_ch() {
|
||||
if let Err(e) = self.lex_multi_line_comment() {
|
||||
return Some(Err(e));
|
||||
}
|
||||
}
|
||||
if let Err(e) = self.lex_comment() {
|
||||
return Some(Err(e));
|
||||
}
|
||||
|
@ -562,6 +623,7 @@ impl Lexer /*<'a>*/ {
|
|||
'r' => s.push('\r'),
|
||||
'n' => s.push('\n'),
|
||||
'\'' => s.push('\''),
|
||||
'"' => s.push('"'),
|
||||
't' => s.push_str(" "), // tab is invalid, so changed into 4 whitespace
|
||||
'\\' => s.push('\\'),
|
||||
_ => {
|
||||
|
@ -630,6 +692,11 @@ impl Iterator for Lexer /*<'a>*/ {
|
|||
return indent_dedent;
|
||||
}
|
||||
if let Some('#') = self.peek_cur_ch() {
|
||||
if let Some('[') = self.peek_next_ch() {
|
||||
if let Err(e) = self.lex_multi_line_comment() {
|
||||
return Some(Err(e));
|
||||
}
|
||||
}
|
||||
if let Err(e) = self.lex_comment() {
|
||||
return Some(Err(e));
|
||||
}
|
||||
|
|
7
compiler/erg_parser/tests/comment.er
Normal file
7
compiler/erg_parser/tests/comment.er
Normal file
|
@ -0,0 +1,7 @@
|
|||
#[
|
||||
aa
|
||||
#[ aa ]#
|
||||
aa
|
||||
]#
|
||||
|
||||
a = 1
|
|
@ -1,12 +1,24 @@
|
|||
# 基本的な構文をパーサーがパスできるかチェックする
|
||||
# Check that a parser can pass the basic syntax
|
||||
#[
|
||||
基本的な構文をパーサーがパスできるかチェックする
|
||||
Check that a parser can pass the basic syntax
|
||||
#[
|
||||
`#[`から`]#`までが複数行コメントとして扱われる
|
||||
コメント内部で入れ子で複数行コメントを付けれるが、閉じ忘れに注意
|
||||
The comment from `#[` to `]#` is treated as a multi-line comment.
|
||||
Nested multi-line comments can be added inside comments, but be careful not to forget to close them.
|
||||
]#
|
||||
]#
|
||||
|
||||
_a = 1_234 + 1113.* 3_000.2e-4 ** 0003 * .4
|
||||
a, _, ...b = five_elem_tuple
|
||||
f x, y =
|
||||
x + y
|
||||
if! True, do!:
|
||||
print! "\\hello, world\""
|
||||
print! "\"\\hello, world\\\""
|
||||
#[
|
||||
indented comment
|
||||
dedented comment
|
||||
]#
|
||||
10.times! do!:
|
||||
if! x.y.z, do!:
|
||||
print! ""
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
0.00, -0.0, .1, 400.
|
||||
|
||||
# Str Literal
|
||||
"", "a", "こんにちは", "\" \\ "
|
||||
"", "a", "こんにちは", "\"\\", "\"\'\\\0\r\n\t"
|
||||
|
||||
# Boolean Litteral
|
||||
True, False
|
||||
|
|
|
@ -18,7 +18,6 @@ fn test_lexer_for_basic() -> ParseResult<()> {
|
|||
let mut lexer = Lexer::new(Input::File(FILE1.into()));
|
||||
let newline = "\n";
|
||||
let /*mut*/ token_array = vec![
|
||||
(Newline, newline),
|
||||
(Newline, newline),
|
||||
(Newline, newline),
|
||||
(Symbol, "_a"),
|
||||
|
@ -37,7 +36,7 @@ fn test_lexer_for_basic() -> ParseResult<()> {
|
|||
(Comma, ","),
|
||||
(UBar, "_"),
|
||||
(Comma, ","),
|
||||
(Spread, "..."), // EllipsisLit
|
||||
(EllipsisLit, "..."),
|
||||
(Symbol, "b"),
|
||||
(Equal, "="),
|
||||
(Symbol, "five_elem_tuple"),
|
||||
|
@ -62,7 +61,8 @@ fn test_lexer_for_basic() -> ParseResult<()> {
|
|||
(Newline, newline),
|
||||
(Indent, " "),
|
||||
(Symbol, "print!"),
|
||||
(StrLit, "\"\\\\hello, world\\\"\""),
|
||||
(StrLit, "\"\"\\hello, world\\\"\""),
|
||||
(Newline, newline),
|
||||
(Newline, newline),
|
||||
(NatLit, "10"),
|
||||
(Dot, "."),
|
||||
|
@ -264,7 +264,9 @@ fn test_lexer_for_literals() -> ParseResult<()> {
|
|||
(Comma, ","),
|
||||
(StrLit, "\"こんにちは\""),
|
||||
(Comma, ","),
|
||||
(StrLit, "\"\\\" \\\\ \""),
|
||||
(StrLit, "\"\"\\\""),
|
||||
(Comma, ","),
|
||||
(StrLit, "\"\"\'\\\0\r\n \""),
|
||||
(Newline, newline),
|
||||
(Newline, newline),
|
||||
(Newline, newline),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue