Start translating ast to instructions.
This commit is contained in:
parent
ae8f89bb4e
commit
aa3f4b3a8b
421
src/ast/build.rs
Normal file
421
src/ast/build.rs
Normal file
@ -0,0 +1,421 @@
|
||||
use crate::ast::{
|
||||
BlockStatement, CompilationUnit, Declaration, Fqn, FunctionDeclaration, GenericArgument,
|
||||
GenericParameter, Identifier, ImplCtor, ImplCtorArg, Parameter, TypeDeclaration, TypeUse,
|
||||
};
|
||||
use crate::parser::{DeimosParser, Rule};
|
||||
use crate::vm::source_code_location::SourceCodeLocation;
|
||||
use pest::iterators::Pair;
|
||||
use pest::Parser;
|
||||
|
||||
fn build_field(field_pair: Pair<Rule>) -> Declaration {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_prop(prop_pair: Pair<Rule>) -> Declaration {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_impl_ctor_arg(impl_ctor_arg_pair: Pair<Rule>) -> ImplCtorArg {
|
||||
let mut is_field = false;
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut r#type: Option<TypeUse> = None;
|
||||
|
||||
for pair in impl_ctor_arg_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::fld => {
|
||||
is_field = true;
|
||||
}
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::type_use => {
|
||||
r#type = Some(build_type_use(pair));
|
||||
}
|
||||
_ => panic!("Unexpected rule: {}", pair),
|
||||
}
|
||||
}
|
||||
|
||||
ImplCtorArg {
|
||||
is_field,
|
||||
identifier: identifier.unwrap(),
|
||||
r#type,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_impl_ctor(impl_ctor_pair: Pair<Rule>) -> ImplCtor {
|
||||
let impl_ctor_args_pair = impl_ctor_pair.into_inner().next().unwrap();
|
||||
let mut args: Vec<ImplCtorArg> = vec![];
|
||||
|
||||
for pair in impl_ctor_args_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::impl_ctor_arg => {
|
||||
args.push(build_impl_ctor_arg(pair));
|
||||
}
|
||||
_ => panic!("Unexpected rule: {}", pair),
|
||||
}
|
||||
}
|
||||
|
||||
ImplCtor { args }
|
||||
}
|
||||
|
||||
fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> GenericArgument {
|
||||
let fqn_pair = generic_argument_pair.into_inner().next().unwrap();
|
||||
GenericArgument {
|
||||
fqn: build_fqn(fqn_pair),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_generic_arguments_declaration(
|
||||
generic_arguments_declaration_pair: Pair<Rule>,
|
||||
) -> Vec<GenericArgument> {
|
||||
let mut generic_arguments: Vec<GenericArgument> = vec![];
|
||||
for pair in generic_arguments_declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::generic_argument => {
|
||||
generic_arguments.push(build_generic_argument(pair));
|
||||
}
|
||||
_ => panic!("Expected only generic_argument rules. Found: {}", pair),
|
||||
}
|
||||
}
|
||||
generic_arguments
|
||||
}
|
||||
|
||||
fn build_generic_parameter(generic_parameter_pair: Pair<Rule>) -> GenericParameter {
|
||||
let identifier_pair = generic_parameter_pair.into_inner().next().unwrap();
|
||||
GenericParameter {
|
||||
identifier: build_identifier(identifier_pair),
|
||||
bound: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_type_use(type_pair: Pair<Rule>) -> TypeUse {
|
||||
let mut fqn: Option<Fqn> = None;
|
||||
let mut generic_arguments_declaration: Option<Vec<GenericArgument>> = None;
|
||||
|
||||
for pair in type_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::fqn => {
|
||||
fqn = Some(build_fqn(pair));
|
||||
}
|
||||
Rule::generic_arguments_declaration => {
|
||||
generic_arguments_declaration = Some(build_generic_arguments_declaration(pair));
|
||||
}
|
||||
_ => panic!(
|
||||
"Expected only fqn or generic_arguments_declaration rules. Found: {}",
|
||||
pair
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
TypeUse {
|
||||
fqn: fqn.unwrap(),
|
||||
generics: generic_arguments_declaration.unwrap_or(vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_generic_parameters_declaration(
|
||||
generic_parameters_declaration_pair: Pair<Rule>,
|
||||
) -> Vec<GenericParameter> {
|
||||
let mut parameters: Vec<GenericParameter> = vec![];
|
||||
for pair in generic_parameters_declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::generic_parameter => {
|
||||
parameters.push(build_generic_parameter(pair));
|
||||
}
|
||||
_ => panic!("Expected only generic_parameter rule. Found: {}", pair),
|
||||
}
|
||||
}
|
||||
parameters
|
||||
}
|
||||
|
||||
fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<TypeUse> {
|
||||
let mut extensions: Vec<TypeUse> = vec![];
|
||||
|
||||
for pair in extends_list_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::type_use => {
|
||||
extensions.push(build_type_use(pair));
|
||||
}
|
||||
_ => panic!("Expected only type rule. Found: {}", pair),
|
||||
}
|
||||
}
|
||||
|
||||
extensions
|
||||
}
|
||||
|
||||
fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>) -> Declaration {
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||
let mut extends: Option<Vec<TypeUse>> = None;
|
||||
let mut declarations: Vec<Declaration> = vec![];
|
||||
|
||||
for pair in interface_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::generic_parameters_declaration => {
|
||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||
}
|
||||
Rule::extends_list => {
|
||||
extends = Some(build_extends_list(pair));
|
||||
}
|
||||
Rule::declaration => {
|
||||
declarations.push(build_declaration(pair));
|
||||
},
|
||||
_ => panic!(
|
||||
"Expected only identifier, generics_declaration, extends_list, or declaration rules. Found: {}",
|
||||
pair
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Declaration::Interface {
|
||||
identifier: identifier.unwrap(),
|
||||
is_extern,
|
||||
is_public,
|
||||
type_declaration: TypeDeclaration::new(
|
||||
generic_parameters.unwrap_or(vec![]),
|
||||
extends.unwrap_or(vec![]),
|
||||
declarations,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_implementation(
|
||||
is_extern: bool,
|
||||
is_public: bool,
|
||||
implementation_pair: Pair<Rule>,
|
||||
) -> Declaration {
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||
let mut impl_ctor: Option<ImplCtor> = None;
|
||||
let mut extends: Option<Vec<TypeUse>> = None;
|
||||
let mut declarations: Vec<Declaration> = vec![];
|
||||
|
||||
for pair in implementation_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::generic_parameters_declaration => {
|
||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||
}
|
||||
Rule::impl_ctor => {
|
||||
impl_ctor = Some(build_impl_ctor(pair));
|
||||
}
|
||||
Rule::extends_list => {
|
||||
extends = Some(build_extends_list(pair));
|
||||
}
|
||||
Rule::declaration => {
|
||||
declarations.push(build_declaration(pair));
|
||||
}
|
||||
_ => panic!("Unexpected rule: {}", pair),
|
||||
}
|
||||
}
|
||||
|
||||
Declaration::Implementation {
|
||||
identifier: identifier.unwrap(),
|
||||
is_extern,
|
||||
is_public,
|
||||
type_declaration: TypeDeclaration::new(
|
||||
generic_parameters.unwrap_or(vec![]),
|
||||
extends.unwrap_or(vec![]),
|
||||
declarations,
|
||||
),
|
||||
impl_ctor,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_module(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_parameter(pair: Pair<Rule>) -> Parameter {
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut declared_type: Option<TypeUse> = None;
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::type_use => {
|
||||
declared_type = Some(build_type_use(pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Parameter {
|
||||
identifier: identifier.unwrap(),
|
||||
declared_type,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_parameters_list(pair: Pair<Rule>) -> Vec<Parameter> {
|
||||
let mut parameters: Vec<Parameter> = vec![];
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::parameter => {
|
||||
parameters.push(build_parameter(pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
parameters
|
||||
}
|
||||
|
||||
fn build_function_body(pair: Pair<Rule>) -> BlockStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_function_equals_body(pair: Pair<Rule>) -> BlockStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration {
|
||||
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut parameters: Option<Vec<Parameter>> = None;
|
||||
let mut return_type: Option<TypeUse> = None;
|
||||
let mut statement: Option<BlockStatement> = None;
|
||||
|
||||
let (line, col) = pair.line_col();
|
||||
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::generic_parameters_declaration => {
|
||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||
}
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::parameters_list => {
|
||||
parameters = Some(build_parameters_list(pair));
|
||||
}
|
||||
Rule::type_use => {
|
||||
return_type = Some(build_type_use(pair));
|
||||
}
|
||||
Rule::function_body => {
|
||||
statement = Some(build_function_body(pair));
|
||||
}
|
||||
Rule::function_equals_body => {
|
||||
statement = Some(build_function_equals_body(pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
Declaration::Function(FunctionDeclaration {
|
||||
is_extern,
|
||||
is_public,
|
||||
identifier: identifier.unwrap(),
|
||||
parameters: parameters.unwrap(),
|
||||
declared_type: return_type,
|
||||
block_statement: statement.unwrap(),
|
||||
source_code_location: SourceCodeLocation {
|
||||
source_file_name: "TODO".to_string(),
|
||||
line,
|
||||
col,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration {
|
||||
let mut is_extern = false;
|
||||
let mut is_public = false;
|
||||
let mut declaration: Option<Declaration> = None;
|
||||
|
||||
for pair in declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::r#extern => {
|
||||
is_extern = true;
|
||||
}
|
||||
Rule::r#pub => {
|
||||
is_public = true;
|
||||
}
|
||||
Rule::interface => {
|
||||
declaration = Some(build_interface(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::implementation => {
|
||||
declaration = Some(build_implementation(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::module => {
|
||||
declaration = Some(build_module(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::function => {
|
||||
declaration = Some(build_function(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::prop => {
|
||||
declaration = Some(build_prop(pair));
|
||||
}
|
||||
Rule::field => {
|
||||
declaration = Some(build_field(pair));
|
||||
}
|
||||
_ => panic!(
|
||||
"Expected only interface, implementation, module, or function rules; found {}",
|
||||
pair
|
||||
),
|
||||
}
|
||||
}
|
||||
declaration.expect("Expected declaration.")
|
||||
}
|
||||
|
||||
fn build_identifier(pair: Pair<Rule>) -> Identifier {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => Identifier {
|
||||
name: String::from(pair.as_str()),
|
||||
},
|
||||
_ => panic!("Expected an identifier."),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn {
|
||||
let mut identifiers: Vec<Identifier> = vec![];
|
||||
for pair in fqn_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
identifiers.push(build_identifier(pair));
|
||||
}
|
||||
_ => panic!("Expected only identifiers."),
|
||||
}
|
||||
}
|
||||
Fqn { identifiers }
|
||||
}
|
||||
|
||||
fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit {
|
||||
let mut namespace: Option<Fqn> = None;
|
||||
let mut declarations: Vec<Declaration> = vec![];
|
||||
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::namespace => {
|
||||
let fqn_pair = pair.into_inner().next().unwrap();
|
||||
namespace = Some(build_fqn(fqn_pair));
|
||||
}
|
||||
Rule::declaration => {
|
||||
declarations.push(build_declaration(pair));
|
||||
}
|
||||
Rule::EOI => {} // ignore
|
||||
_ => panic!(
|
||||
"Expected only namespace, declaration, or EOI rules, found: {}",
|
||||
pair
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
CompilationUnit {
|
||||
namespace,
|
||||
declarations,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_ast(src: &str) -> CompilationUnit {
|
||||
let pair = DeimosParser::parse(Rule::compilation_unit, src)
|
||||
.expect("Unsuccessful parse.")
|
||||
.next()
|
||||
.expect("Expcted compilation_unit.");
|
||||
match pair.as_rule() {
|
||||
Rule::compilation_unit => build_compilation_unit(pair),
|
||||
_ => panic!("Expected compilation_unit rule."),
|
||||
}
|
||||
}
|
542
src/ast/mod.rs
542
src/ast/mod.rs
@ -1,5 +1,7 @@
|
||||
use crate::parser::{DeimosParser, Rule};
|
||||
use pest::{iterators::Pair, Parser};
|
||||
use crate::vm::source_code_location::SourceCodeLocation;
|
||||
use pest::Parser;
|
||||
|
||||
pub mod build;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CompilationUnit {
|
||||
@ -7,11 +9,39 @@ pub struct CompilationUnit {
|
||||
declarations: Vec<Declaration>,
|
||||
}
|
||||
|
||||
impl CompilationUnit {
|
||||
pub fn namespace(&self) -> &Option<Fqn> {
|
||||
&self.namespace
|
||||
}
|
||||
|
||||
pub fn declarations(&self) -> &Vec<Declaration> {
|
||||
&self.declarations
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Fqn {
|
||||
identifiers: Vec<Identifier>,
|
||||
}
|
||||
|
||||
impl Fqn {
|
||||
pub fn new(identifiers: Vec<Identifier>) -> Self {
|
||||
Fqn { identifiers }
|
||||
}
|
||||
|
||||
pub fn identifiers(&self) -> &Vec<Identifier> {
|
||||
&self.identifiers
|
||||
}
|
||||
|
||||
pub fn push_identifier(&mut self, identifier: Identifier) {
|
||||
self.identifiers.push(identifier);
|
||||
}
|
||||
|
||||
pub fn pop_identifier(&mut self) {
|
||||
self.identifiers.pop();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Declaration {
|
||||
Interface {
|
||||
@ -33,16 +63,34 @@ pub enum Declaration {
|
||||
is_public: bool,
|
||||
declarations: Vec<Declaration>,
|
||||
},
|
||||
Function {
|
||||
Function(FunctionDeclaration),
|
||||
Prop(Prop),
|
||||
Field(Field),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionDeclaration {
|
||||
source_code_location: SourceCodeLocation,
|
||||
identifier: Identifier,
|
||||
is_extern: bool,
|
||||
is_public: bool,
|
||||
parameters: Vec<Parameter>,
|
||||
declared_type: Option<TypeUse>,
|
||||
statement: Statement,
|
||||
},
|
||||
Prop(Prop),
|
||||
Field(Field),
|
||||
block_statement: BlockStatement,
|
||||
}
|
||||
|
||||
impl FunctionDeclaration {
|
||||
pub fn source_code_location(&self) -> &SourceCodeLocation {
|
||||
&self.source_code_location
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn block_statement(&self) -> &BlockStatement {
|
||||
&self.block_statement
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -66,11 +114,17 @@ impl TypeDeclaration {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Identifier {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl Identifier {
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GenericParameter {
|
||||
identifier: Identifier,
|
||||
@ -118,11 +172,71 @@ pub struct Field {
|
||||
r#type: TypeUse,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BlockStatement {
|
||||
statements: Vec<Statement>,
|
||||
}
|
||||
|
||||
impl BlockStatement {
|
||||
pub fn statements(&self) -> &Vec<Statement> {
|
||||
&self.statements
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Statement {
|
||||
BlockStatement { statements: Vec<Statement> },
|
||||
CallStatement,
|
||||
AssignmentStatement,
|
||||
CallStatement(CallExpression),
|
||||
AssignStatement(AssignExpression),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallExpression {
|
||||
receiver: Expression,
|
||||
actuals_list: Vec<Expression>,
|
||||
source_code_location: SourceCodeLocation,
|
||||
}
|
||||
|
||||
impl CallExpression {
|
||||
pub fn receiver(&self) -> &Expression {
|
||||
&self.receiver
|
||||
}
|
||||
|
||||
pub fn actuals_list(&self) -> &Vec<Expression> {
|
||||
&self.actuals_list
|
||||
}
|
||||
|
||||
pub fn source_code_location(&self) -> &SourceCodeLocation {
|
||||
&self.source_code_location
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssignExpression {
|
||||
left: LValue,
|
||||
right: Expression,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Expression {
|
||||
CallExpression(Box<CallExpression>),
|
||||
AssignExpression(Box<AssignExpression>),
|
||||
LValue(Box<LValue>),
|
||||
Literal(Box<Literal>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LValue {
|
||||
Fqn(Fqn),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Literal {
|
||||
IntegerLiteral(i32),
|
||||
LongLiteral(i64),
|
||||
DoubleLiteral(f64),
|
||||
USizeLiteral(usize),
|
||||
StringLiteral(String),
|
||||
BooleanLiteral(bool),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -130,409 +244,3 @@ pub struct Parameter {
|
||||
identifier: Identifier,
|
||||
declared_type: Option<TypeUse>,
|
||||
}
|
||||
|
||||
fn build_field(field_pair: Pair<Rule>) -> Declaration {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_prop(prop_pair: Pair<Rule>) -> Declaration {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_impl_ctor_arg(impl_ctor_arg_pair: Pair<Rule>) -> ImplCtorArg {
|
||||
let mut is_field = false;
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut r#type: Option<TypeUse> = None;
|
||||
|
||||
for pair in impl_ctor_arg_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::fld => {
|
||||
is_field = true;
|
||||
}
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::type_use => {
|
||||
r#type = Some(build_type_use(pair));
|
||||
}
|
||||
_ => panic!("Unexpected rule: {}", pair),
|
||||
}
|
||||
}
|
||||
|
||||
ImplCtorArg {
|
||||
is_field,
|
||||
identifier: identifier.unwrap(),
|
||||
r#type,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_impl_ctor(impl_ctor_pair: Pair<Rule>) -> ImplCtor {
|
||||
let impl_ctor_args_pair = impl_ctor_pair.into_inner().next().unwrap();
|
||||
let mut args: Vec<ImplCtorArg> = vec![];
|
||||
|
||||
for pair in impl_ctor_args_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::impl_ctor_arg => {
|
||||
args.push(build_impl_ctor_arg(pair));
|
||||
}
|
||||
_ => panic!("Unexpected rule: {}", pair),
|
||||
}
|
||||
}
|
||||
|
||||
ImplCtor { args }
|
||||
}
|
||||
|
||||
fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> GenericArgument {
|
||||
let fqn_pair = generic_argument_pair.into_inner().next().unwrap();
|
||||
GenericArgument {
|
||||
fqn: build_fqn(fqn_pair),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_generic_arguments_declaration(
|
||||
generic_arguments_declaration_pair: Pair<Rule>,
|
||||
) -> Vec<GenericArgument> {
|
||||
let mut generic_arguments: Vec<GenericArgument> = vec![];
|
||||
for pair in generic_arguments_declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::generic_argument => {
|
||||
generic_arguments.push(build_generic_argument(pair));
|
||||
}
|
||||
_ => panic!("Expected only generic_argument rules. Found: {}", pair),
|
||||
}
|
||||
}
|
||||
generic_arguments
|
||||
}
|
||||
|
||||
fn build_generic_parameter(generic_parameter_pair: Pair<Rule>) -> GenericParameter {
|
||||
let identifier_pair = generic_parameter_pair.into_inner().next().unwrap();
|
||||
GenericParameter {
|
||||
identifier: build_identifier(identifier_pair),
|
||||
bound: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_type_use(type_pair: Pair<Rule>) -> TypeUse {
|
||||
let mut fqn: Option<Fqn> = None;
|
||||
let mut generic_arguments_declaration: Option<Vec<GenericArgument>> = None;
|
||||
|
||||
for pair in type_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::fqn => {
|
||||
fqn = Some(build_fqn(pair));
|
||||
}
|
||||
Rule::generic_arguments_declaration => {
|
||||
generic_arguments_declaration = Some(build_generic_arguments_declaration(pair));
|
||||
}
|
||||
_ => panic!(
|
||||
"Expected only fqn or generic_arguments_declaration rules. Found: {}",
|
||||
pair
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
TypeUse {
|
||||
fqn: fqn.unwrap(),
|
||||
generics: generic_arguments_declaration.unwrap_or(vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_generic_parameters_declaration(
|
||||
generic_parameters_declaration_pair: Pair<Rule>,
|
||||
) -> Vec<GenericParameter> {
|
||||
let mut parameters: Vec<GenericParameter> = vec![];
|
||||
for pair in generic_parameters_declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::generic_parameter => {
|
||||
parameters.push(build_generic_parameter(pair));
|
||||
}
|
||||
_ => panic!("Expected only generic_parameter rule. Found: {}", pair),
|
||||
}
|
||||
}
|
||||
parameters
|
||||
}
|
||||
|
||||
fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<TypeUse> {
|
||||
let mut extensions: Vec<TypeUse> = vec![];
|
||||
|
||||
for pair in extends_list_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::type_use => {
|
||||
extensions.push(build_type_use(pair));
|
||||
}
|
||||
_ => panic!("Expected only type rule. Found: {}", pair),
|
||||
}
|
||||
}
|
||||
|
||||
extensions
|
||||
}
|
||||
|
||||
fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>) -> Declaration {
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||
let mut extends: Option<Vec<TypeUse>> = None;
|
||||
let mut declarations: Vec<Declaration> = vec![];
|
||||
|
||||
for pair in interface_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::generic_parameters_declaration => {
|
||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||
}
|
||||
Rule::extends_list => {
|
||||
extends = Some(build_extends_list(pair));
|
||||
}
|
||||
Rule::declaration => {
|
||||
declarations.push(build_declaration(pair));
|
||||
},
|
||||
_ => panic!(
|
||||
"Expected only identifier, generics_declaration, extends_list, or declaration rules. Found: {}",
|
||||
pair
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Declaration::Interface {
|
||||
identifier: identifier.unwrap(),
|
||||
is_extern,
|
||||
is_public,
|
||||
type_declaration: TypeDeclaration::new(
|
||||
generic_parameters.unwrap_or(vec![]),
|
||||
extends.unwrap_or(vec![]),
|
||||
declarations,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_implementation(
|
||||
is_extern: bool,
|
||||
is_public: bool,
|
||||
implementation_pair: Pair<Rule>,
|
||||
) -> Declaration {
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||
let mut impl_ctor: Option<ImplCtor> = None;
|
||||
let mut extends: Option<Vec<TypeUse>> = None;
|
||||
let mut declarations: Vec<Declaration> = vec![];
|
||||
|
||||
for pair in implementation_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::generic_parameters_declaration => {
|
||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||
}
|
||||
Rule::impl_ctor => {
|
||||
impl_ctor = Some(build_impl_ctor(pair));
|
||||
}
|
||||
Rule::extends_list => {
|
||||
extends = Some(build_extends_list(pair));
|
||||
}
|
||||
Rule::declaration => {
|
||||
declarations.push(build_declaration(pair));
|
||||
}
|
||||
_ => panic!("Unexpected rule: {}", pair),
|
||||
}
|
||||
}
|
||||
|
||||
Declaration::Implementation {
|
||||
identifier: identifier.unwrap(),
|
||||
is_extern,
|
||||
is_public,
|
||||
type_declaration: TypeDeclaration::new(
|
||||
generic_parameters.unwrap_or(vec![]),
|
||||
extends.unwrap_or(vec![]),
|
||||
declarations,
|
||||
),
|
||||
impl_ctor,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_module(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_parameter(pair: Pair<Rule>) -> Parameter {
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut declared_type: Option<TypeUse> = None;
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::type_use => {
|
||||
declared_type = Some(build_type_use(pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Parameter {
|
||||
identifier: identifier.unwrap(),
|
||||
declared_type,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_parameters_list(pair: Pair<Rule>) -> Vec<Parameter> {
|
||||
let mut parameters: Vec<Parameter> = vec![];
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::parameter => {
|
||||
parameters.push(build_parameter(pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
parameters
|
||||
}
|
||||
|
||||
fn build_function_body(pair: Pair<Rule>) -> Statement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_function_equals_body(pair: Pair<Rule>) -> Statement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration {
|
||||
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||
let mut identifier: Option<Identifier> = None;
|
||||
let mut parameters: Option<Vec<Parameter>> = None;
|
||||
let mut return_type: Option<TypeUse> = None;
|
||||
let mut statement: Option<Statement> = None;
|
||||
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::generic_parameters_declaration => {
|
||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||
}
|
||||
Rule::identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::parameters_list => {
|
||||
parameters = Some(build_parameters_list(pair));
|
||||
}
|
||||
Rule::type_use => {
|
||||
return_type = Some(build_type_use(pair));
|
||||
}
|
||||
Rule::function_body => {
|
||||
statement = Some(build_function_body(pair));
|
||||
}
|
||||
Rule::function_equals_body => {
|
||||
statement = Some(build_function_equals_body(pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
Declaration::Function {
|
||||
is_extern,
|
||||
is_public,
|
||||
identifier: identifier.unwrap(),
|
||||
parameters: parameters.unwrap(),
|
||||
declared_type: return_type,
|
||||
statement: statement.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration {
|
||||
let mut is_extern = false;
|
||||
let mut is_public = false;
|
||||
let mut declaration: Option<Declaration> = None;
|
||||
|
||||
for pair in declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::r#extern => {
|
||||
is_extern = true;
|
||||
}
|
||||
Rule::r#pub => {
|
||||
is_public = true;
|
||||
}
|
||||
Rule::interface => {
|
||||
declaration = Some(build_interface(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::implementation => {
|
||||
declaration = Some(build_implementation(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::module => {
|
||||
declaration = Some(build_module(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::function => {
|
||||
declaration = Some(build_function(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::prop => {
|
||||
declaration = Some(build_prop(pair));
|
||||
}
|
||||
Rule::field => {
|
||||
declaration = Some(build_field(pair));
|
||||
}
|
||||
_ => panic!(
|
||||
"Expected only interface, implementation, module, or function rules; found {}",
|
||||
pair
|
||||
),
|
||||
}
|
||||
}
|
||||
declaration.expect("Expected declaration.")
|
||||
}
|
||||
|
||||
fn build_identifier(pair: Pair<Rule>) -> Identifier {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => Identifier {
|
||||
name: String::from(pair.as_str()),
|
||||
},
|
||||
_ => panic!("Expected an identifier."),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn {
|
||||
let mut identifiers: Vec<Identifier> = vec![];
|
||||
for pair in fqn_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
identifiers.push(build_identifier(pair));
|
||||
}
|
||||
_ => panic!("Expected only identifiers."),
|
||||
}
|
||||
}
|
||||
Fqn { identifiers }
|
||||
}
|
||||
|
||||
fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit {
|
||||
let mut namespace: Option<Fqn> = None;
|
||||
let mut declarations: Vec<Declaration> = vec![];
|
||||
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::namespace => {
|
||||
let fqn_pair = pair.into_inner().next().unwrap();
|
||||
namespace = Some(build_fqn(fqn_pair));
|
||||
}
|
||||
Rule::declaration => {
|
||||
declarations.push(build_declaration(pair));
|
||||
}
|
||||
Rule::EOI => {} // ignore
|
||||
_ => panic!(
|
||||
"Expected only namespace, declaration, or EOI rules, found: {}",
|
||||
pair
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
CompilationUnit {
|
||||
namespace,
|
||||
declarations,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_ast(src: &str) -> CompilationUnit {
|
||||
let pair = DeimosParser::parse(Rule::compilation_unit, src)
|
||||
.expect("Unsuccessful parse.")
|
||||
.next()
|
||||
.expect("Expcted compilation_unit.");
|
||||
match pair.as_rule() {
|
||||
Rule::compilation_unit => build_compilation_unit(pair),
|
||||
_ => panic!("Expected compilation_unit rule."),
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deimos::ast::build_ast;
|
||||
use deimos::ast::build::build_ast;
|
||||
|
||||
pub fn dump_ast(path: &PathBuf) {
|
||||
let src = std::fs::read_to_string(path)
|
||||
.expect(&format!("Could not read {:?}", path));
|
||||
let src = std::fs::read_to_string(path).expect(&format!("Could not read {:?}", path));
|
||||
let ast = build_ast(&src);
|
||||
println!("{:?}", ast);
|
||||
}
|
||||
|
@ -16,9 +16,7 @@ struct Cli {
|
||||
#[derive(Debug, Subcommand)]
|
||||
enum Commands {
|
||||
#[command(arg_required_else_help = true)]
|
||||
AstDump {
|
||||
paths: Vec<PathBuf>
|
||||
}
|
||||
AstDump { paths: Vec<PathBuf> },
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@ -31,4 +29,3 @@ fn main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ fn main() {
|
||||
source_code_location: SourceCodeLocation {
|
||||
source_file_name: String::from("greeter.dm"),
|
||||
line: 4,
|
||||
char: 5,
|
||||
col: 5,
|
||||
},
|
||||
},
|
||||
// unwind from call
|
||||
@ -54,10 +54,12 @@ fn main() {
|
||||
source_code_location: SourceCodeLocation {
|
||||
source_file_name: String::from("greeter.dm"),
|
||||
line: 5,
|
||||
char: 13,
|
||||
col: 13,
|
||||
},
|
||||
},
|
||||
Pop { destination_register: Some(0) }, // restore r0
|
||||
Pop {
|
||||
destination_register: Some(0),
|
||||
}, // restore r0
|
||||
TakeReturnValue {
|
||||
destination_register: 1,
|
||||
},
|
||||
@ -70,7 +72,7 @@ fn main() {
|
||||
source_code_location: SourceCodeLocation {
|
||||
source_file_name: String::from("greeter.dm"),
|
||||
line: 5,
|
||||
char: 5,
|
||||
col: 5,
|
||||
},
|
||||
},
|
||||
Pop {
|
||||
@ -97,7 +99,7 @@ fn main() {
|
||||
SourceCodeLocation {
|
||||
source_file_name: String::from("greeter.dm"),
|
||||
line: 3,
|
||||
char: 1,
|
||||
col: 1,
|
||||
},
|
||||
);
|
||||
|
||||
@ -116,7 +118,7 @@ fn main() {
|
||||
SourceCodeLocation {
|
||||
source_file_name: String::from("greeter.dm"),
|
||||
line: 8,
|
||||
char: 1,
|
||||
col: 1,
|
||||
},
|
||||
);
|
||||
|
||||
|
10
src/compile/declared_type.rs
Normal file
10
src/compile/declared_type.rs
Normal file
@ -0,0 +1,10 @@
|
||||
pub enum DeclaredType {
|
||||
Function(FunctionType),
|
||||
}
|
||||
|
||||
pub enum FunctionType {
|
||||
StaticFunction,
|
||||
ObjectFunction,
|
||||
StaticPlatformFunction,
|
||||
ObjectPlatformFunction,
|
||||
}
|
164
src/compile/mod.rs
Normal file
164
src/compile/mod.rs
Normal file
@ -0,0 +1,164 @@
|
||||
use crate::ast::{
|
||||
AssignExpression, BlockStatement, CallExpression, CompilationUnit, Declaration, Expression,
|
||||
Fqn, FunctionDeclaration, Identifier, LValue, Statement,
|
||||
};
|
||||
use crate::object_file::{DvmObjectFile, DvmPath};
|
||||
use crate::vm::function::DvmFunction;
|
||||
use crate::vm::instruction::Instruction;
|
||||
use declared_type::{DeclaredType, FunctionType};
|
||||
use std::rc::Rc;
|
||||
use symbol_table::SymbolTable;
|
||||
|
||||
mod declared_type;
|
||||
mod symbol;
|
||||
mod symbol_table;
|
||||
|
||||
struct CompilationState {
|
||||
fqn_part_stack: Vec<Identifier>,
|
||||
}
|
||||
|
||||
impl CompilationState {
|
||||
fn push_fqn_identifier(&mut self, identifier: &Identifier) {
|
||||
self.fqn_part_stack.push(identifier.clone());
|
||||
}
|
||||
|
||||
fn pop_fqn_identifier(&mut self) {
|
||||
self.fqn_part_stack.pop();
|
||||
}
|
||||
|
||||
fn get_current_fqn(&self) -> Fqn {
|
||||
Fqn::new(self.fqn_part_stack.clone())
|
||||
}
|
||||
}
|
||||
|
||||
struct CompilationContext {
|
||||
source_file_name: String,
|
||||
symbol_table: SymbolTable,
|
||||
}
|
||||
|
||||
fn compile_call_expression(
|
||||
context: &CompilationContext,
|
||||
call_expression: &CallExpression,
|
||||
instructions: &mut Vec<Instruction>,
|
||||
) {
|
||||
match call_expression.receiver() {
|
||||
Expression::LValue(lvalue) => {
|
||||
let lvalue = &**lvalue;
|
||||
if let LValue::Fqn(fqn) = lvalue {
|
||||
let symbol = context.symbol_table.resolve(fqn);
|
||||
match symbol.declared_type() {
|
||||
DeclaredType::Function(function_type) => match function_type {
|
||||
FunctionType::StaticFunction => {
|
||||
instructions.push(Instruction::InvokeStatic {
|
||||
function_name: Rc::new(convert_fqn(&fqn)),
|
||||
source_code_location: call_expression
|
||||
.source_code_location()
|
||||
.clone(),
|
||||
});
|
||||
}
|
||||
_ => todo!(),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_assign_expression(
|
||||
assign_expression: &AssignExpression,
|
||||
instruction: &mut Vec<Instruction>,
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn convert_statement(
|
||||
context: &CompilationContext,
|
||||
statement: &Statement,
|
||||
instructions: &mut Vec<Instruction>,
|
||||
) {
|
||||
match statement {
|
||||
Statement::CallStatement(call_expression) => {
|
||||
compile_call_expression(context, call_expression, instructions);
|
||||
}
|
||||
Statement::AssignStatement(assign_expression) => {
|
||||
compile_assign_expression(assign_expression, instructions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_block_statement(
|
||||
context: &CompilationContext,
|
||||
block_statement: &BlockStatement,
|
||||
) -> Vec<Instruction> {
|
||||
let mut instructions = vec![];
|
||||
for statement in block_statement.statements() {
|
||||
convert_statement(context, statement, &mut instructions);
|
||||
}
|
||||
instructions
|
||||
}
|
||||
|
||||
fn convert_static_function(
|
||||
compilation_state: &CompilationState,
|
||||
context: &CompilationContext,
|
||||
function_declaration: &FunctionDeclaration,
|
||||
) -> DvmFunction {
|
||||
let mut fqn = compilation_state.get_current_fqn();
|
||||
fqn.push_identifier(function_declaration.identifier().clone());
|
||||
|
||||
let instructions = convert_block_statement(context, function_declaration.block_statement());
|
||||
|
||||
DvmFunction::new(
|
||||
&convert_fqn(&fqn),
|
||||
&instructions,
|
||||
function_declaration.source_code_location().clone(),
|
||||
)
|
||||
}
|
||||
|
||||
fn convert_fqn(fqn: &Fqn) -> String {
|
||||
let mut as_string = String::new();
|
||||
let mut i = 0;
|
||||
let identifiers = fqn.identifiers();
|
||||
while i < identifiers.len() {
|
||||
as_string.push_str(identifiers[i].name());
|
||||
i += 1;
|
||||
if i < identifiers.len() {
|
||||
as_string.push_str("::");
|
||||
}
|
||||
}
|
||||
as_string
|
||||
}
|
||||
|
||||
fn make_path(file_name: &str, file_namespace: &Option<Fqn>) -> DvmPath {
|
||||
if let Some(namespace) = file_namespace {
|
||||
DvmPath::new(&convert_fqn(namespace), file_name)
|
||||
} else {
|
||||
DvmPath::new("", file_name)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn convert(file_name: &str, ast: CompilationUnit) -> DvmObjectFile {
|
||||
let path = make_path(file_name, ast.namespace());
|
||||
let mut object_file = DvmObjectFile::new(path);
|
||||
|
||||
let mut state = CompilationState {
|
||||
fqn_part_stack: Vec::new(),
|
||||
};
|
||||
let context = CompilationContext {
|
||||
source_file_name: file_name.to_string(),
|
||||
symbol_table: SymbolTable {},
|
||||
};
|
||||
|
||||
for declaration in ast.declarations() {
|
||||
match declaration {
|
||||
Declaration::Function(function_declaration) => {
|
||||
let function = convert_static_function(&state, &context, function_declaration);
|
||||
object_file.add_function(function);
|
||||
}
|
||||
_ => todo!("Unimplemented declaration {:?}", declaration),
|
||||
}
|
||||
}
|
||||
object_file
|
||||
}
|
17
src/compile/symbol.rs
Normal file
17
src/compile/symbol.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use crate::ast::Fqn;
|
||||
use crate::compile::declared_type::DeclaredType;
|
||||
|
||||
pub struct Symbol {
|
||||
fqn: Fqn,
|
||||
declared_type: DeclaredType,
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
pub fn fqn(&self) -> &Fqn {
|
||||
&self.fqn
|
||||
}
|
||||
|
||||
pub fn declared_type(&self) -> &DeclaredType {
|
||||
&self.declared_type
|
||||
}
|
||||
}
|
10
src/compile/symbol_table.rs
Normal file
10
src/compile/symbol_table.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use crate::ast::Fqn;
|
||||
use crate::compile::symbol::Symbol;
|
||||
|
||||
pub struct SymbolTable {}
|
||||
|
||||
impl SymbolTable {
|
||||
pub fn resolve(&self, fqn: &Fqn) -> Symbol {
|
||||
todo!()
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
use crate::ast::CompilationUnit;
|
||||
use crate::parser::{DeimosParser, Rule};
|
||||
use crate::module::DmModule;
|
||||
|
||||
pub fn compile(module: &mut DmModule, compilation_unit: CompilationUnit) {
|
||||
todo!()
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#![allow(warnings)]
|
||||
pub mod ast;
|
||||
pub mod compiler;
|
||||
pub mod compile;
|
||||
pub mod module;
|
||||
pub mod object_file;
|
||||
pub mod parser;
|
||||
|
@ -176,7 +176,7 @@ impl Display for DvmCall {
|
||||
self.function_name,
|
||||
self.source_code_location.source_file_name,
|
||||
self.source_code_location.line,
|
||||
self.source_code_location.char
|
||||
self.source_code_location.col
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,16 @@
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SourceCodeLocation {
|
||||
pub source_file_name: String,
|
||||
pub line: i64,
|
||||
pub char: i64,
|
||||
pub line: usize,
|
||||
pub col: usize,
|
||||
}
|
||||
|
||||
impl SourceCodeLocation {
|
||||
pub fn new(source_file_name: &str, line: usize, col: usize) -> Self {
|
||||
SourceCodeLocation {
|
||||
source_file_name: source_file_name.to_string(),
|
||||
line,
|
||||
col
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user