docs/parser/ast.md
The parser AST describes the high-level syntactic structure of Enso, as well as containing robust and descriptive parser errors directly in the AST.
<!-- MarkdownTOC levels="2,3" autolink="true" --> <!-- /MarkdownTOC -->The parser AST needs to account for the following:
Name type, removing the distinction between different names found
in the lexer. This should provide functions is_var, is_opr,
and is_ref.Invalid nodes, but these should be given a descriptive
error as to why the construct is invalid.Ambiguous nodes, where a macro cannot be resolved in
an unambiguous fashion.Each node should contain:
The actionables for this section are:
- Flesh out the design for the AST based on the requirements of the various parser phases.
The single source of truth for the AST is its Rust implementation. Therefore, in order to not get out of sync, the Scala AST implementation is generated during compilation directly from the Rust ast source file.
The command for generating the Scala ast and storing it in the file
foo/ast.scala is following:
cargo run -p ast -- --generate-scala-ast foo/ast.scala.
Since there isn't 1:1 mapping between Rust and Scala, only a subset of Rust's structures is supported. These are follows.
u32 | i32 | u16 | i16 | i8 => Int,
usize | isize | u64 | i64 => Long,
u8 => Byte,
char => Char,
Vec => Vector,
Uuid => UUID,
Note: It is assumed, that Enso runs on 64bit platforms. Therefore,
usizeandisizeare converted toLong.
struct Foo<X> { x: X<z::Y>, .. }
Is converted into:
case class Foo[X](x: X[Z.Y], ..)
enum Foo{ Bar{x:X}, Baz{y:Y, z:Z} }
Is converted into:
sealed trait Foo
case class Bar(x:X) extends Foo
case class Baz(y:Y, z:Z) extends Foo
enum Enum { Foo(x::Foo), Bar(x::Bar), Baz(y::Baz) }
mod x {
pub struct Foo { .. }
pub struct Bar { .. }
}
mod y {
pub struct Baz { .. }
}
Is converted into:
sealed trait Enum
object X {
sealed trait X extends Enum
case class Foo(..) extends X
case class Bar(..) extends X
}
object Y {
sealed trait Y extends Enum
case class Baz(..) extends Y
}
mod foo { .. }
Is converted into:
object Foo { .. }
Furthermore, the content of ast.rs is wrapped inside additional object Ast,
in order to support top level type aliases.
type A<X> = B<X,Y>;
Is converted into:
type A[X] = B[X, Y]
Note that in contrast to Rust, Scala doesn't support types outside objects.