Compare commits

...

2 Commits

Author SHA1 Message Date
Jesse Brault
1263d84802 Work on grammar and AST building. 2025-04-14 08:00:05 -05:00
Jesse Brault
94f496a63d Sketch DvmObjectFile type and related functions. 2025-04-14 07:59:51 -05:00
9 changed files with 333 additions and 125 deletions

View File

@ -1,5 +1,5 @@
use pest::{iterators::{Pair, Pairs}, Parser};
use crate::parser::{DeimosParser, Rule}; use crate::parser::{DeimosParser, Rule};
use pest::{iterators::Pair, Parser};
#[derive(Debug)] #[derive(Debug)]
pub struct CompilationUnit { pub struct CompilationUnit {
@ -9,7 +9,7 @@ pub struct CompilationUnit {
#[derive(Debug)] #[derive(Debug)]
pub struct Fqn { pub struct Fqn {
identifiers: Vec<Identifier> identifiers: Vec<Identifier>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -25,7 +25,7 @@ pub enum Declaration {
is_extern: bool, is_extern: bool,
is_public: bool, is_public: bool,
type_declaration: TypeDeclaration, type_declaration: TypeDeclaration,
impl_ctor: Option<ImplCtor> impl_ctor: Option<ImplCtor>,
}, },
Module { Module {
identifier: Identifier, identifier: Identifier,
@ -37,92 +37,98 @@ pub enum Declaration {
identifier: Identifier, identifier: Identifier,
is_extern: bool, is_extern: bool,
is_public: bool, is_public: bool,
statement: Statement parameters: Vec<Parameter>,
declared_type: Option<TypeUse>,
statement: Statement,
}, },
Prop(Prop), Prop(Prop),
Field(Field) Field(Field),
} }
#[derive(Debug)] #[derive(Debug)]
pub struct TypeDeclaration { pub struct TypeDeclaration {
generics: Vec<GenericParameter>, generics: Vec<GenericParameter>,
extends: Vec<Type>, extends: Vec<TypeUse>,
declarations: Vec<Declaration>, declarations: Vec<Declaration>,
} }
impl TypeDeclaration { impl TypeDeclaration {
pub fn new(generics: Vec<GenericParameter>, extends: Vec<Type>, declarations: Vec<Declaration>) -> TypeDeclaration { pub fn new(
generics: Vec<GenericParameter>,
extends: Vec<TypeUse>,
declarations: Vec<Declaration>,
) -> TypeDeclaration {
TypeDeclaration { TypeDeclaration {
generics, generics,
extends, extends,
declarations declarations,
} }
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Identifier { pub struct Identifier {
name: String name: String,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct GenericParameter { pub struct GenericParameter {
identifier: Identifier, identifier: Identifier,
bound: Option<GenericBound> bound: Option<GenericBound>,
} }
#[derive(Debug)] #[derive(Debug)]
pub enum GenericBound { pub enum GenericBound {
Extends { Extends { fqn: Fqn },
fqn: Fqn Super { fqn: Fqn },
},
Super {
fqn: Fqn
}
} }
#[derive(Debug)] #[derive(Debug)]
pub struct GenericArgument { pub struct GenericArgument {
fqn: Fqn fqn: Fqn,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Type { pub struct TypeUse {
fqn: Fqn, fqn: Fqn,
generics: Vec<GenericArgument> generics: Vec<GenericArgument>,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct ImplCtor { pub struct ImplCtor {
args: Vec<ImplCtorArg> args: Vec<ImplCtorArg>,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct ImplCtorArg { pub struct ImplCtorArg {
is_field: bool, is_field: bool,
identifier: Identifier, identifier: Identifier,
r#type: Option<Type> r#type: Option<TypeUse>,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Prop { pub struct Prop {
identifier: Identifier, identifier: Identifier,
r#type: Type r#type: TypeUse,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Field { pub struct Field {
identifier: Identifier, identifier: Identifier,
r#type: Type r#type: TypeUse,
} }
#[derive(Debug)] #[derive(Debug)]
pub enum Statement { pub enum Statement {
BlockStatement { BlockStatement { statements: Vec<Statement> },
statements: Vec<Statement>
},
CallStatement, CallStatement,
AssignmentStatement AssignmentStatement,
}
#[derive(Debug)]
pub struct Parameter {
identifier: Identifier,
declared_type: Option<TypeUse>,
} }
fn build_field(field_pair: Pair<Rule>) -> Declaration { fn build_field(field_pair: Pair<Rule>) -> Declaration {
@ -136,27 +142,27 @@ fn build_prop(prop_pair: Pair<Rule>) -> Declaration {
fn build_impl_ctor_arg(impl_ctor_arg_pair: Pair<Rule>) -> ImplCtorArg { fn build_impl_ctor_arg(impl_ctor_arg_pair: Pair<Rule>) -> ImplCtorArg {
let mut is_field = false; let mut is_field = false;
let mut identifier: Option<Identifier> = None; let mut identifier: Option<Identifier> = None;
let mut r#type: Option<Type> = None; let mut r#type: Option<TypeUse> = None;
for pair in impl_ctor_arg_pair.into_inner() { for pair in impl_ctor_arg_pair.into_inner() {
match pair.as_rule() { match pair.as_rule() {
Rule::fld => { Rule::fld => {
is_field = true; is_field = true;
}, }
Rule::identifier => { Rule::identifier => {
identifier = Some(build_identifier(pair)); identifier = Some(build_identifier(pair));
}, }
Rule::r#type => { Rule::type_use => {
r#type = Some(build_type(pair)); r#type = Some(build_type_use(pair));
}, }
_ => panic!("Unexpected rule: {}", pair) _ => panic!("Unexpected rule: {}", pair),
} }
} }
ImplCtorArg { ImplCtorArg {
is_field, is_field,
identifier: identifier.unwrap(), identifier: identifier.unwrap(),
r#type r#type,
} }
} }
@ -169,30 +175,30 @@ fn build_impl_ctor(impl_ctor_pair: Pair<Rule>) -> ImplCtor {
Rule::impl_ctor_arg => { Rule::impl_ctor_arg => {
args.push(build_impl_ctor_arg(pair)); args.push(build_impl_ctor_arg(pair));
} }
_ => panic!("Unexpected rule: {}", pair) _ => panic!("Unexpected rule: {}", pair),
} }
} }
ImplCtor { ImplCtor { args }
args
}
} }
fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> GenericArgument { fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> GenericArgument {
let fqn_pair = generic_argument_pair.into_inner().next().unwrap(); let fqn_pair = generic_argument_pair.into_inner().next().unwrap();
GenericArgument { GenericArgument {
fqn: build_fqn(fqn_pair) fqn: build_fqn(fqn_pair),
} }
} }
fn build_generic_arguments_declaration(generic_arguments_declaration_pair: Pair<Rule>) -> Vec<GenericArgument> { fn build_generic_arguments_declaration(
generic_arguments_declaration_pair: Pair<Rule>,
) -> Vec<GenericArgument> {
let mut generic_arguments: Vec<GenericArgument> = vec![]; let mut generic_arguments: Vec<GenericArgument> = vec![];
for pair in generic_arguments_declaration_pair.into_inner() { for pair in generic_arguments_declaration_pair.into_inner() {
match pair.as_rule() { match pair.as_rule() {
Rule::generic_argument => { Rule::generic_argument => {
generic_arguments.push(build_generic_argument(pair)); generic_arguments.push(build_generic_argument(pair));
} }
_ => panic!("Expected only generic_argument rules. Found: {}", pair) _ => panic!("Expected only generic_argument rules. Found: {}", pair),
} }
} }
generic_arguments generic_arguments
@ -206,7 +212,7 @@ fn build_generic_parameter(generic_parameter_pair: Pair<Rule>) -> GenericParamet
} }
} }
fn build_type(type_pair: Pair<Rule>) -> Type { fn build_type_use(type_pair: Pair<Rule>) -> TypeUse {
let mut fqn: Option<Fqn> = None; let mut fqn: Option<Fqn> = None;
let mut generic_arguments_declaration: Option<Vec<GenericArgument>> = None; let mut generic_arguments_declaration: Option<Vec<GenericArgument>> = None;
@ -218,38 +224,43 @@ fn build_type(type_pair: Pair<Rule>) -> Type {
Rule::generic_arguments_declaration => { Rule::generic_arguments_declaration => {
generic_arguments_declaration = Some(build_generic_arguments_declaration(pair)); generic_arguments_declaration = Some(build_generic_arguments_declaration(pair));
} }
_ => panic!("Expected only fqn or generic_arguments_declaration rules. Found: {}", pair) _ => panic!(
"Expected only fqn or generic_arguments_declaration rules. Found: {}",
pair
),
} }
} }
Type { TypeUse {
fqn: fqn.unwrap(), fqn: fqn.unwrap(),
generics: generic_arguments_declaration.unwrap_or(vec![]) generics: generic_arguments_declaration.unwrap_or(vec![]),
} }
} }
fn build_generic_parameters_declaration(generic_parameters_declaration_pair: Pair<Rule>) -> Vec<GenericParameter> { fn build_generic_parameters_declaration(
generic_parameters_declaration_pair: Pair<Rule>,
) -> Vec<GenericParameter> {
let mut parameters: Vec<GenericParameter> = vec![]; let mut parameters: Vec<GenericParameter> = vec![];
for pair in generic_parameters_declaration_pair.into_inner() { for pair in generic_parameters_declaration_pair.into_inner() {
match pair.as_rule() { match pair.as_rule() {
Rule::generic_parameter => { Rule::generic_parameter => {
parameters.push(build_generic_parameter(pair)); parameters.push(build_generic_parameter(pair));
} }
_ => panic!("Expected only generic_parameter rule. Found: {}", pair) _ => panic!("Expected only generic_parameter rule. Found: {}", pair),
} }
} }
parameters parameters
} }
fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<Type> { fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<TypeUse> {
let mut extensions: Vec<Type> = vec![]; let mut extensions: Vec<TypeUse> = vec![];
for pair in extends_list_pair.into_inner() { for pair in extends_list_pair.into_inner() {
match pair.as_rule() { match pair.as_rule() {
Rule::r#type => { Rule::type_use => {
extensions.push(build_type(pair)); extensions.push(build_type_use(pair));
} }
_ => panic!("Expected only type rule. Found: {}", pair) _ => panic!("Expected only type rule. Found: {}", pair),
} }
} }
@ -259,7 +270,7 @@ fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<Type> {
fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>) -> Declaration { fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>) -> Declaration {
let mut identifier: Option<Identifier> = None; let mut identifier: Option<Identifier> = None;
let mut generic_parameters: Option<Vec<GenericParameter>> = None; let mut generic_parameters: Option<Vec<GenericParameter>> = None;
let mut extends: Option<Vec<Type>> = None; let mut extends: Option<Vec<TypeUse>> = None;
let mut declarations: Vec<Declaration> = vec![]; let mut declarations: Vec<Declaration> = vec![];
for pair in interface_pair.into_inner() { for pair in interface_pair.into_inner() {
@ -290,36 +301,40 @@ fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>)
type_declaration: TypeDeclaration::new( type_declaration: TypeDeclaration::new(
generic_parameters.unwrap_or(vec![]), generic_parameters.unwrap_or(vec![]),
extends.unwrap_or(vec![]), extends.unwrap_or(vec![]),
declarations declarations,
) ),
} }
} }
fn build_implementation(is_extern: bool, is_public: bool, implementation_pair: Pair<Rule>) -> Declaration { fn build_implementation(
is_extern: bool,
is_public: bool,
implementation_pair: Pair<Rule>,
) -> Declaration {
let mut identifier: Option<Identifier> = None; let mut identifier: Option<Identifier> = None;
let mut generic_parameters: Option<Vec<GenericParameter>> = None; let mut generic_parameters: Option<Vec<GenericParameter>> = None;
let mut impl_ctor: Option<ImplCtor> = None; let mut impl_ctor: Option<ImplCtor> = None;
let mut extends: Option<Vec<Type>> = None; let mut extends: Option<Vec<TypeUse>> = None;
let mut declarations: Vec<Declaration> = vec![]; let mut declarations: Vec<Declaration> = vec![];
for pair in implementation_pair.into_inner() { for pair in implementation_pair.into_inner() {
match pair.as_rule() { match pair.as_rule() {
Rule::identifier => { Rule::identifier => {
identifier = Some(build_identifier(pair)); identifier = Some(build_identifier(pair));
}, }
Rule::generic_parameters_declaration => { Rule::generic_parameters_declaration => {
generic_parameters = Some(build_generic_parameters_declaration(pair)); generic_parameters = Some(build_generic_parameters_declaration(pair));
}, }
Rule::impl_ctor => { Rule::impl_ctor => {
impl_ctor = Some(build_impl_ctor(pair)); impl_ctor = Some(build_impl_ctor(pair));
}, }
Rule::extends_list => { Rule::extends_list => {
extends = Some(build_extends_list(pair)); extends = Some(build_extends_list(pair));
}, }
Rule::declaration => { Rule::declaration => {
declarations.push(build_declaration(pair)); declarations.push(build_declaration(pair));
} }
_ => panic!("Unexpected rule: {}", pair) _ => panic!("Unexpected rule: {}", pair),
} }
} }
@ -330,9 +345,9 @@ fn build_implementation(is_extern: bool, is_public: bool, implementation_pair: P
type_declaration: TypeDeclaration::new( type_declaration: TypeDeclaration::new(
generic_parameters.unwrap_or(vec![]), generic_parameters.unwrap_or(vec![]),
extends.unwrap_or(vec![]), extends.unwrap_or(vec![]),
declarations declarations,
), ),
impl_ctor impl_ctor,
} }
} }
@ -340,10 +355,88 @@ fn build_module(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declarati
todo!() todo!()
} }
fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration { 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!() 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 { fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration {
let mut is_extern = false; let mut is_extern = false;
let mut is_public = false; let mut is_public = false;
@ -353,29 +446,32 @@ fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration {
match pair.as_rule() { match pair.as_rule() {
Rule::r#extern => { Rule::r#extern => {
is_extern = true; is_extern = true;
}, }
Rule::r#pub => { Rule::r#pub => {
is_public = true; is_public = true;
} }
Rule::interface => { Rule::interface => {
declaration = Some(build_interface(is_extern, is_public, pair)); declaration = Some(build_interface(is_extern, is_public, pair));
}, }
Rule::implementation => { Rule::implementation => {
declaration = Some(build_implementation(is_extern, is_public, pair)); declaration = Some(build_implementation(is_extern, is_public, pair));
}, }
Rule::module => { Rule::module => {
declaration = Some(build_module(is_extern, is_public, pair)); declaration = Some(build_module(is_extern, is_public, pair));
}, }
Rule::function => { Rule::function => {
declaration = Some(build_function(is_extern, is_public, pair)); declaration = Some(build_function(is_extern, is_public, pair));
}, }
Rule::prop => { Rule::prop => {
declaration = Some(build_prop(pair)); declaration = Some(build_prop(pair));
} }
Rule::field => { Rule::field => {
declaration = Some(build_field(pair)); declaration = Some(build_field(pair));
} }
_ => panic!("Expected only interface, implementation, module, or function rules; found {}", pair) _ => panic!(
"Expected only interface, implementation, module, or function rules; found {}",
pair
),
} }
} }
declaration.expect("Expected declaration.") declaration.expect("Expected declaration.")
@ -383,12 +479,10 @@ fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration {
fn build_identifier(pair: Pair<Rule>) -> Identifier { fn build_identifier(pair: Pair<Rule>) -> Identifier {
match pair.as_rule() { match pair.as_rule() {
Rule::identifier => { Rule::identifier => Identifier {
Identifier { name: String::from(pair.as_str()),
name: String::from(pair.as_str()) },
} _ => panic!("Expected an identifier."),
}
_ => panic!("Expected an identifier.")
} }
} }
@ -399,15 +493,13 @@ fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn {
Rule::identifier => { Rule::identifier => {
identifiers.push(build_identifier(pair)); identifiers.push(build_identifier(pair));
} }
_ => panic!("Expected only identifiers.") _ => panic!("Expected only identifiers."),
} }
} }
Fqn { Fqn { identifiers }
identifiers
}
} }
fn build_compilation_unit(pair: Pair<Rule>)-> CompilationUnit { fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit {
let mut namespace: Option<Fqn> = None; let mut namespace: Option<Fqn> = None;
let mut declarations: Vec<Declaration> = vec![]; let mut declarations: Vec<Declaration> = vec![];
@ -421,13 +513,16 @@ fn build_compilation_unit(pair: Pair<Rule>)-> CompilationUnit {
declarations.push(build_declaration(pair)); declarations.push(build_declaration(pair));
} }
Rule::EOI => {} // ignore Rule::EOI => {} // ignore
_ => panic!("Expected only namespace, declaration, or EOI rules, found: {}", pair) _ => panic!(
"Expected only namespace, declaration, or EOI rules, found: {}",
pair
),
} }
} }
CompilationUnit { CompilationUnit {
namespace, namespace,
declarations declarations,
} }
} }
@ -437,10 +532,7 @@ pub fn build_ast(src: &str) -> CompilationUnit {
.next() .next()
.expect("Expcted compilation_unit."); .expect("Expcted compilation_unit.");
match pair.as_rule() { match pair.as_rule() {
Rule::compilation_unit => { Rule::compilation_unit => build_compilation_unit(pair),
build_compilation_unit(pair) _ => panic!("Expected compilation_unit rule."),
},
_ => panic!("Expected compilation_unit rule.")
} }
} }

View File

@ -1,3 +1,4 @@
use deimos::object_file::{DvmObjectFile, DvmPath};
use deimos::vm::constant::DvmConstant; use deimos::vm::constant::DvmConstant;
use deimos::vm::function::DvmFunction; use deimos::vm::function::DvmFunction;
use deimos::vm::instruction::{Immediate, Instruction, Location}; use deimos::vm::instruction::{Immediate, Instruction, Location};
@ -16,6 +17,8 @@ fn main() {
// fn main() { // fn main() {
// println "Hello, World!" // println "Hello, World!"
// } // }
let mut greeter_object_file = DvmObjectFile::new(DvmPath::new("greeter", "greeter.dmo"));
let main_instructions = vec![ let main_instructions = vec![
Instruction::MoveImmediate { Instruction::MoveImmediate {
destination: Location::Register(0), destination: Location::Register(0),
@ -55,10 +58,16 @@ fn main() {
char: 1, char: 1,
}, },
); );
greeter_object_file.add_function(main_function);
let mut state = DvmState::new(); let mut state = DvmState::new();
let mut context = DvmContext::new(Rc::new(main_function)); let mut context = DvmContext::new("greeter::main");
context.add_platform_functions(get_std_lib_platform_functions()); context.add_platform_functions(get_std_lib_platform_functions());
greeter_object_file.load_to_context(&mut context, &|path| {
todo!()
});
let exit_code = run_main_function(&mut state, &context); let exit_code = run_main_function(&mut state, &context);
dump_state(&state, "After main!"); dump_state(&state, "After main!");

View File

@ -1,7 +1,8 @@
#![allow(warnings)] #![allow(warnings)]
mod compiler;
pub mod parser;
mod util;
pub mod vm;
pub mod ast; pub mod ast;
pub mod compiler;
pub mod module; pub mod module;
pub mod object_file;
pub mod parser;
pub mod util;
pub mod vm;

76
src/object_file/mod.rs Normal file
View File

@ -0,0 +1,76 @@
use crate::vm::function::DvmFunction;
use crate::vm::implementation::DvmImplementation;
use crate::vm::interface::DvmInterface;
use crate::vm::DvmContext;
pub struct DvmObjectFile {
path: DvmPath,
dependencies: Vec<DvmPath>,
interfaces: Vec<DvmInterface>,
implementations: Vec<DvmImplementation>,
functions: Vec<DvmFunction>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DvmPath {
base_fqn: String,
file_name: String,
}
impl DvmPath {
pub fn new(base_fqn: &str, file_name: &str) -> Self {
DvmPath {
base_fqn: base_fqn.to_string(),
file_name: file_name.to_string(),
}
}
}
impl DvmObjectFile {
pub fn new(path: DvmPath) -> Self {
DvmObjectFile {
path,
dependencies: vec![],
interfaces: vec![],
implementations: vec![],
functions: vec![],
}
}
pub fn add_function(&mut self, function: DvmFunction) {
self.functions.push(function);
}
pub fn add_dependency(&mut self, path: DvmPath) {
self.dependencies.push(path);
}
pub fn load_to_context(
self,
context: &mut DvmContext,
linker: &impl Fn(&DvmPath) -> DvmObjectFile,
) {
if context.is_object_file_loaded(&self.path) {
return;
}
// Offload our own declarations
for interface in self.interfaces {
context.add_interface(interface);
}
for implementation in self.implementations {
context.add_implementation(implementation);
}
for function in self.functions {
context.add_static_function(function);
}
context.mark_object_file_as_loaded(self.path);
// Recursively load dependencies
for dependency in &self.dependencies {
let dependency_object_file = linker(dependency);
dependency_object_file.load_to_context(context, linker);
}
}
}

View File

@ -11,34 +11,34 @@ extern = { "extern" }
pub = { "pub" } pub = { "pub" }
interface = { "int" ~ identifier ~ generic_parameters_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } interface = { "int" ~ identifier ~ generic_parameters_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? }
extends_list = { ":" ~ type ~ ( "+" ~ type )* } extends_list = { ":" ~ type_use ~ ( "+" ~ type_use )* }
implementation = { "impl" ~ identifier ~ generic_parameters_declaration? ~ impl_ctor? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } implementation = { "impl" ~ identifier ~ generic_parameters_declaration? ~ impl_ctor? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? }
impl_ctor = { "(" ~ impl_ctor_args? ~ ")" } impl_ctor = { "(" ~ impl_ctor_args? ~ ")" }
impl_ctor_args = { impl_ctor_arg ~ ( "," ~ impl_ctor_arg )* } impl_ctor_args = { impl_ctor_arg ~ ( "," ~ impl_ctor_arg )* }
impl_ctor_arg = { fld? ~ identifier ~ ( ":" ~ type )? } impl_ctor_arg = { fld? ~ identifier ~ ( ":" ~ type_use )? }
fld = { "fld" } fld = { "fld" }
module = { "mod" ~ identifier ~ "{" ~ declaration* ~ "}" } module = { "mod" ~ identifier ~ "{" ~ declaration* ~ "}" }
property = { identifier ~ ( ":" ~ type )? } property = { identifier ~ ( ":" ~ type_use )? }
function = { "fn" ~ generic_parameters_declaration? ~ identifier ~ "(" ~ args_list? ~ ")" ~ ( ":" ~ type )? ~ ( function_body | function_equals_body ) } function = { "fn" ~ generic_parameters_declaration? ~ identifier ~ "(" ~ parameters_list? ~ ")" ~ ( ":" ~ type_use )? ~ ( function_body | function_equals_body ) }
function_equals_body = { "=" ~ expression } function_equals_body = { "=" ~ expression }
function_body = { "{" ~ statement* ~ "}" } function_body = { "{" ~ statement* ~ "}" }
type = { fqn ~ generic_arguments_declaration? } type_use = { fqn ~ generic_arguments_declaration? }
generic_parameters_declaration = { "<" ~ generic_parameter ~ ( "," ~ generic_parameter )* ~ ">" } generic_parameters_declaration = { "<" ~ generic_parameter ~ ( "," ~ generic_parameter )* ~ ">" }
generic_parameter = { identifier } generic_parameter = { identifier }
generic_arguments_declaration = { "<" ~ generic_argument ~ ( "," ~ generic_argument )* ~ ">" } generic_arguments_declaration = { "<" ~ generic_argument ~ ( "," ~ generic_argument )* ~ ">" }
generic_argument = { fqn } generic_argument = { fqn }
args_list = { arg ~ ( "," ~ arg )* } parameters_list = { parameter ~ ( "," ~ parameter )* }
arg = { identifier ~ ( ":" ~ "..."? ~ type )? } parameter = { identifier ~ ( ":" ~ "..."? ~ type_use )? }
prop = { identifier ~ ":" ~ type } prop = { identifier ~ ":" ~ type_use }
field = { fld ~ identifier ~ ":" ~ type } field = { fld ~ identifier ~ ":" ~ type_use }
statement = { call_stmt } statement = { call_stmt }

View File

@ -1,6 +1,6 @@
use crate::vm::field::DvmField; use crate::vm::field::DvmField;
use crate::vm::function::DvmFunction; use crate::vm::function::DvmFunction;
use crate::vm::interface::DmInterface; use crate::vm::interface::DvmInterface;
use crate::vm::method::DvmMethod; use crate::vm::method::DvmMethod;
use crate::vm::object::DvmObject; use crate::vm::object::DvmObject;
use std::collections::HashMap; use std::collections::HashMap;
@ -10,7 +10,7 @@ use std::rc::Rc;
#[derive(Debug, Eq)] #[derive(Debug, Eq)]
pub struct DvmImplementation { pub struct DvmImplementation {
fqn: String, fqn: String,
interface: Option<Rc<DmInterface>>, interface: Option<Rc<DvmInterface>>,
static_functions: HashMap<String, Rc<DvmFunction>>, static_functions: HashMap<String, Rc<DvmFunction>>,
methods: HashMap<String, Rc<DvmMethod>>, methods: HashMap<String, Rc<DvmMethod>>,
fields: HashMap<String, Rc<DvmField>>, fields: HashMap<String, Rc<DvmField>>,
@ -23,7 +23,7 @@ impl PartialEq for DvmImplementation {
} }
impl DvmImplementation { impl DvmImplementation {
pub fn new(fqn: &str, interface: Option<Rc<DmInterface>>) -> Self { pub fn new(fqn: &str, interface: Option<Rc<DvmInterface>>) -> Self {
DvmImplementation { DvmImplementation {
fqn: fqn.to_string(), fqn: fqn.to_string(),
interface, interface,
@ -59,7 +59,7 @@ impl DvmImplementation {
pub fn find_field(&self, name: &str, self_object: &DvmObject) -> Option<Rc<DvmField>> { pub fn find_field(&self, name: &str, self_object: &DvmObject) -> Option<Rc<DvmField>> {
self.fields.get(name).cloned() self.fields.get(name).cloned()
} }
pub fn field_count(&self) -> usize { pub fn field_count(&self) -> usize {
self.fields.len() self.fields.len()
} }

View File

@ -3,21 +3,21 @@ use crate::vm::virtual_method::DmVirtualMethod;
use std::rc::Rc; use std::rc::Rc;
#[derive(Debug, Eq)] #[derive(Debug, Eq)]
pub struct DmInterface { pub struct DvmInterface {
fqn: String, fqn: String,
static_functions: Vec<Rc<DvmFunction>>, static_functions: Vec<Rc<DvmFunction>>,
virtual_methods: Vec<DmVirtualMethod>, virtual_methods: Vec<DmVirtualMethod>,
} }
impl PartialEq for DmInterface { impl PartialEq for DvmInterface {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.fqn == other.fqn self.fqn == other.fqn
} }
} }
impl DmInterface { impl DvmInterface {
pub fn new(fqn: &str) -> Self { pub fn new(fqn: &str) -> Self {
DmInterface { DvmInterface {
fqn: fqn.to_string(), fqn: fqn.to_string(),
static_functions: Vec::new(), static_functions: Vec::new(),
virtual_methods: Vec::new(), virtual_methods: Vec::new(),

View File

@ -5,13 +5,13 @@ mod write;
use crate::vm::function::DvmFunction; use crate::vm::function::DvmFunction;
use crate::vm::implementation::DvmImplementation; use crate::vm::implementation::DvmImplementation;
use crate::vm::interface::DmInterface; use crate::vm::interface::DvmInterface;
use std::rc::Rc; use std::rc::Rc;
pub struct DmLib { pub struct DmLib {
name: String, name: String,
constants: Vec<DmConstant>, constants: Vec<DmConstant>,
interfaces: Vec<Rc<DmInterface>>, interfaces: Vec<Rc<DvmInterface>>,
implementations: Vec<Rc<DvmImplementation>>, implementations: Vec<Rc<DvmImplementation>>,
functions: Vec<Rc<DvmFunction>>, functions: Vec<Rc<DvmFunction>>,
} }
@ -39,11 +39,11 @@ impl DmLib {
self.constants.push(constant); self.constants.push(constant);
} }
pub fn interfaces(&self) -> &Vec<Rc<DmInterface>> { pub fn interfaces(&self) -> &Vec<Rc<DvmInterface>> {
&self.interfaces &self.interfaces
} }
pub fn add_interface(&mut self, interface: DmInterface) { pub fn add_interface(&mut self, interface: DvmInterface) {
self.interfaces.push(Rc::new(interface)); self.interfaces.push(Rc::new(interface));
} }

View File

@ -1,12 +1,12 @@
mod array; pub mod array;
pub mod constant; pub mod constant;
mod field; pub mod field;
pub mod function; pub mod function;
pub mod implementation; pub mod implementation;
pub mod instruction; pub mod instruction;
mod interface; pub mod interface;
pub mod lib; pub mod lib;
mod method; pub mod method;
pub mod object; pub mod object;
pub mod op_codes; pub mod op_codes;
pub mod platform; pub mod platform;
@ -14,12 +14,14 @@ pub mod source_code_location;
pub mod r#type; pub mod r#type;
pub mod util; pub mod util;
pub mod value; pub mod value;
mod virtual_method; pub mod virtual_method;
use crate::object_file::DvmPath;
use crate::vm::array::DvmArray; use crate::vm::array::DvmArray;
use crate::vm::constant::{DvmConstant, DvmConstantArray}; use crate::vm::constant::{DvmConstant, DvmConstantArray};
use crate::vm::implementation::DvmImplementation; use crate::vm::implementation::DvmImplementation;
use crate::vm::instruction::{Immediate, Instruction, Location}; use crate::vm::instruction::{Immediate, Instruction, Location};
use crate::vm::interface::DvmInterface;
use crate::vm::object::DvmObject; use crate::vm::object::DvmObject;
use crate::vm::value::DvmValue; use crate::vm::value::DvmValue;
use function::DvmFunction; use function::DvmFunction;
@ -95,19 +97,23 @@ impl DvmState {
} }
pub struct DvmContext { pub struct DvmContext {
main_function: Rc<DvmFunction>, main_function: String,
interfaces: HashMap<String, Rc<DvmInterface>>,
implementations: HashMap<String, Rc<DvmImplementation>>, implementations: HashMap<String, Rc<DvmImplementation>>,
static_functions: HashMap<String, Rc<DvmFunction>>, static_functions: HashMap<String, Rc<DvmFunction>>,
platform_functions: HashMap<String, PlatformFunction>, platform_functions: HashMap<String, PlatformFunction>,
loaded_object_files: Vec<DvmPath>,
} }
impl DvmContext { impl DvmContext {
pub fn new(main_function: Rc<DvmFunction>) -> Self { pub fn new(main_function: &str) -> Self {
DvmContext { DvmContext {
main_function, main_function: main_function.to_string(),
interfaces: HashMap::new(),
implementations: HashMap::new(), implementations: HashMap::new(),
static_functions: HashMap::new(), static_functions: HashMap::new(),
platform_functions: HashMap::new(), platform_functions: HashMap::new(),
loaded_object_files: vec![],
} }
} }
@ -119,6 +125,29 @@ impl DvmContext {
self.platform_functions.insert(fqn, platform_function); self.platform_functions.insert(fqn, platform_function);
} }
} }
pub fn is_object_file_loaded(&self, path: &DvmPath) -> bool {
self.loaded_object_files.contains(path)
}
pub fn add_interface(&mut self, interface: DvmInterface) {
self.interfaces
.insert(interface.fqn().to_string(), Rc::new(interface));
}
pub fn add_implementation(&mut self, implementation: DvmImplementation) {
self.implementations
.insert(implementation.fqn().to_string(), Rc::new(implementation));
}
pub fn add_static_function(&mut self, function: DvmFunction) {
self.static_functions
.insert(function.fqn().to_string(), Rc::new(function));
}
pub fn mark_object_file_as_loaded(&mut self, path: DvmPath) {
self.loaded_object_files.push(path);
}
} }
pub struct DvmCall { pub struct DvmCall {
@ -281,7 +310,8 @@ fn immediate_to_value(immediate: &Immediate) -> DvmValue {
} }
pub fn run_main_function(state: &mut DvmState, context: &DvmContext) -> i32 { pub fn run_main_function(state: &mut DvmState, context: &DvmContext) -> i32 {
let main_function = context.main_function.clone(); let main_function = context.static_functions.get(&context.main_function)
.expect(&format!("No such main function: {}", context.main_function));
push_call_frame( push_call_frame(
Rc::new(main_function.fqn().to_string()), Rc::new(main_function.fqn().to_string()),
main_function.source_code_location().clone(), main_function.source_code_location().clone(),