Repl with expressions working, let statements still not working.
This commit is contained in:
parent
ed6f15a8a9
commit
7b76771843
@ -1,7 +1,7 @@
|
|||||||
mod repl;
|
mod repl;
|
||||||
mod run;
|
mod run;
|
||||||
|
|
||||||
use crate::repl::repl;
|
use crate::repl::{repl, repl_2};
|
||||||
use crate::run::compile_and_run_script;
|
use crate::run::compile_and_run_script;
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -44,7 +44,7 @@ fn main() {
|
|||||||
compile_and_run_script(script, *show_asm, *show_ir, register_count);
|
compile_and_run_script(script, *show_asm, *show_ir, register_count);
|
||||||
}
|
}
|
||||||
SubCommand::Repl => {
|
SubCommand::Repl => {
|
||||||
repl(&mut io::stdin().lock(), register_count);
|
repl_2(&mut io::stdin().lock(), register_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
126
dm/src/repl.rs
126
dm/src/repl.rs
@ -7,9 +7,9 @@ use dmc_lib::ir::ir_variable::IrVariable;
|
|||||||
use dmc_lib::ir::variable_locations::VariableLocations;
|
use dmc_lib::ir::variable_locations::VariableLocations;
|
||||||
use dmc_lib::lexer::Lexer;
|
use dmc_lib::lexer::Lexer;
|
||||||
use dmc_lib::offset_counter::OffsetCounter;
|
use dmc_lib::offset_counter::OffsetCounter;
|
||||||
use dmc_lib::parser::parse_expression;
|
use dmc_lib::parser::{parse_expression, parse_let_statement};
|
||||||
use dmc_lib::semantic_analysis::AnalysisContext;
|
use dmc_lib::semantic_analysis::AnalysisContext;
|
||||||
use dmc_lib::semantic_analysis::scope::ScopeId;
|
use dmc_lib::semantic_analysis::scope::{Scope, ScopeId};
|
||||||
use dmc_lib::symbol::variable_symbol::VariableSymbol;
|
use dmc_lib::symbol::variable_symbol::VariableSymbol;
|
||||||
use dmc_lib::symbol_table::SymbolTable;
|
use dmc_lib::symbol_table::SymbolTable;
|
||||||
use dmc_lib::token::TokenKind;
|
use dmc_lib::token::TokenKind;
|
||||||
@ -310,8 +310,17 @@ pub fn repl_2(read: &mut impl BufRead, register_count: usize) {
|
|||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
|
|
||||||
let mut analysis_context = AnalysisContext::new();
|
let mut analysis_context = AnalysisContext::new();
|
||||||
let mut function_scope_id: Option<ScopeId> = None;
|
let root_scope_id = analysis_context.root_scope_id();
|
||||||
let fqn: Rc<str> = Rc::from("repl");
|
analysis_context
|
||||||
|
.scopes_mut()
|
||||||
|
.push(Scope::new(Some(root_scope_id))); // function scope
|
||||||
|
let function_scope_id = analysis_context.scopes().len() - 1;
|
||||||
|
analysis_context
|
||||||
|
.scopes_mut()
|
||||||
|
.push(Scope::new(Some(function_scope_id))); // body scope
|
||||||
|
let body_scope_id = analysis_context.scopes().len() - 1;
|
||||||
|
|
||||||
|
let fqn: Rc<str> = Rc::from("__repl");
|
||||||
let mut variable_locations = VariableLocations::new();
|
let mut variable_locations = VariableLocations::new();
|
||||||
let mut constants_table = ConstantsTable::new();
|
let mut constants_table = ConstantsTable::new();
|
||||||
|
|
||||||
@ -342,6 +351,91 @@ pub fn repl_2(read: &mut impl BufRead, register_count: usize) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
match first_token.kind() {
|
||||||
|
TokenKind::Let => {
|
||||||
|
let compile_result = compile_let_statement_2(
|
||||||
|
input,
|
||||||
|
&mut analysis_context,
|
||||||
|
body_scope_id,
|
||||||
|
&fqn,
|
||||||
|
&mut variable_locations,
|
||||||
|
register_count,
|
||||||
|
&mut constants_table,
|
||||||
|
);
|
||||||
|
match compile_result {
|
||||||
|
Ok(function) => {
|
||||||
|
dvm_context
|
||||||
|
.functions_mut()
|
||||||
|
.insert(function.name_owned(), function);
|
||||||
|
}
|
||||||
|
Err(diagnostics) => {
|
||||||
|
for diagnostic in diagnostics {
|
||||||
|
eprintln!("{}", diagnostic.message());
|
||||||
|
}
|
||||||
|
buffer.clear();
|
||||||
|
continue 'repl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let compile_result = compile_expression_2(
|
||||||
|
input,
|
||||||
|
&mut analysis_context,
|
||||||
|
body_scope_id,
|
||||||
|
&fqn,
|
||||||
|
&mut variable_locations,
|
||||||
|
register_count,
|
||||||
|
&mut constants_table,
|
||||||
|
);
|
||||||
|
match compile_result {
|
||||||
|
Ok(function) => {
|
||||||
|
dvm_context
|
||||||
|
.functions_mut()
|
||||||
|
.insert(function.name_owned(), function);
|
||||||
|
}
|
||||||
|
Err(diagnostics) => {
|
||||||
|
for diagnostic in diagnostics {
|
||||||
|
eprintln!("{}", diagnostic.message());
|
||||||
|
}
|
||||||
|
buffer.clear();
|
||||||
|
continue 'repl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (name, content) in constants_table.string_constants() {
|
||||||
|
dvm_context.constants_mut().insert(
|
||||||
|
name.clone(),
|
||||||
|
Constant::String(StringConstant::new(name, content)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut call_stack = CallStack::new();
|
||||||
|
prepare_for_instruction_loop(&dvm_context, "__repl", &mut call_stack, &[]);
|
||||||
|
|
||||||
|
// copy all old locals to current call frame's stack
|
||||||
|
// this has to be done with indexing because the preparation above creates space for them
|
||||||
|
for (i, operand) in repl_fn_stack_locals.iter().enumerate() {
|
||||||
|
let target_index = call_stack.top().fp() + i;
|
||||||
|
call_stack.top_mut().stack_mut()[target_index] = operand.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = loop_instructions(
|
||||||
|
&dvm_context,
|
||||||
|
&mut vec![Operand::Null; register_count],
|
||||||
|
&mut call_stack,
|
||||||
|
);
|
||||||
|
|
||||||
|
// copy the top frame's stack locals back to OUR stack locals for next iteration
|
||||||
|
repl_fn_stack_locals = std::mem::take(call_stack.top_mut().stack_mut());
|
||||||
|
|
||||||
|
if let Some(value) = result {
|
||||||
|
println!("{}", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,3 +465,27 @@ fn compile_expression_2(
|
|||||||
constants_table,
|
constants_table,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile_let_statement_2(
|
||||||
|
input: &str,
|
||||||
|
analysis_context: &mut AnalysisContext,
|
||||||
|
function_scope_id: ScopeId,
|
||||||
|
fqn: &Rc<str>,
|
||||||
|
variable_locations: &mut VariableLocations,
|
||||||
|
register_count: usize,
|
||||||
|
constants_table: &mut ConstantsTable,
|
||||||
|
) -> Result<Function, Diagnostics> {
|
||||||
|
let (maybe_let_statement, parse_diagnostics) = parse_let_statement(input);
|
||||||
|
if !parse_diagnostics.is_empty() {
|
||||||
|
return Err(parse_diagnostics);
|
||||||
|
}
|
||||||
|
compile_statement_to_synthetic_function(
|
||||||
|
&Statement::Let(maybe_let_statement.unwrap()),
|
||||||
|
analysis_context,
|
||||||
|
function_scope_id,
|
||||||
|
fqn.clone(),
|
||||||
|
variable_locations,
|
||||||
|
register_count,
|
||||||
|
constants_table,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrAllocate {
|
pub struct IrAllocate {
|
||||||
class_fqn: Rc<str>,
|
class_fqn: Rc<str>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::ir::ir_variable::IrVariableId;
|
|||||||
use crate::ir::register_allocation::VrUser;
|
use crate::ir::register_allocation::VrUser;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrAssign {
|
pub struct IrAssign {
|
||||||
destination: IrVariableId,
|
destination: IrVariableId,
|
||||||
initializer: Box<IrOperation>,
|
initializer: Box<IrOperation>,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum IrBinaryOperator {
|
pub enum IrBinaryOperator {
|
||||||
Multiply,
|
Multiply,
|
||||||
Divide,
|
Divide,
|
||||||
@ -17,6 +18,7 @@ pub enum IrBinaryOperator {
|
|||||||
BitwiseOr,
|
BitwiseOr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrBinaryOperation {
|
pub struct IrBinaryOperation {
|
||||||
left: Box<IrExpression>,
|
left: Box<IrExpression>,
|
||||||
right: Box<IrExpression>,
|
right: Box<IrExpression>,
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
pub type IrBlockId = usize;
|
pub type IrBlockId = usize;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrBlock {
|
pub struct IrBlock {
|
||||||
id: IrBlockId,
|
id: IrBlockId,
|
||||||
debug_label: String,
|
debug_label: String,
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use std::collections::HashSet;
|
|||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrCall {
|
pub struct IrCall {
|
||||||
function_name: Rc<str>,
|
function_name: Rc<str>,
|
||||||
arguments: Vec<IrExpression>,
|
arguments: Vec<IrExpression>,
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use std::collections::HashSet;
|
|||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum IrExpression {
|
pub enum IrExpression {
|
||||||
Parameter(IrParameterId),
|
Parameter(IrParameterId),
|
||||||
Variable(IrVariableId),
|
Variable(IrVariableId),
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use dvm_lib::vm::function::Function;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrFunction {
|
pub struct IrFunction {
|
||||||
fqn: Rc<str>,
|
fqn: Rc<str>,
|
||||||
parameters: Vec<IrParameter>,
|
parameters: Vec<IrParameter>,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrGetFieldRef {
|
pub struct IrGetFieldRef {
|
||||||
self_variable_or_parameter: IrParameterOrVariable,
|
self_variable_or_parameter: IrParameterOrVariable,
|
||||||
field_index: usize,
|
field_index: usize,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrGetFieldRefMut {
|
pub struct IrGetFieldRefMut {
|
||||||
self_variable_or_parameter: IrParameterOrVariable,
|
self_variable_or_parameter: IrParameterOrVariable,
|
||||||
field_index: usize,
|
field_index: usize,
|
||||||
|
|||||||
@ -10,6 +10,7 @@ use crate::ir::register_allocation::VrUser;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum IrOperation {
|
pub enum IrOperation {
|
||||||
GetFieldRef(IrGetFieldRef),
|
GetFieldRef(IrGetFieldRef),
|
||||||
GetFieldRefMut(IrGetFieldRefMut),
|
GetFieldRefMut(IrGetFieldRefMut),
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
pub type IrParameterId = usize;
|
pub type IrParameterId = usize;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrParameter {
|
pub struct IrParameter {
|
||||||
name: Rc<str>,
|
name: Rc<str>,
|
||||||
type_info: IrTypeInfo,
|
type_info: IrTypeInfo,
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::ir::register_allocation::VrUser;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrReadField {
|
pub struct IrReadField {
|
||||||
field_ref_variable: IrVariableId,
|
field_ref_variable: IrVariableId,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrReturn {
|
pub struct IrReturn {
|
||||||
value: Option<IrExpression>,
|
value: Option<IrExpression>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrSetField {
|
pub struct IrSetField {
|
||||||
field_ref_variable: IrVariableId,
|
field_ref_variable: IrVariableId,
|
||||||
initializer: Box<IrExpression>,
|
initializer: Box<IrExpression>,
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use crate::ir::ir_variable::IrVariableId;
|
|||||||
use crate::ir::register_allocation::VrUser;
|
use crate::ir::register_allocation::VrUser;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum IrStatement {
|
pub enum IrStatement {
|
||||||
Assign(IrAssign),
|
Assign(IrAssign),
|
||||||
Call(IrCall),
|
Call(IrCall),
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
pub type IrVariableId = usize;
|
pub type IrVariableId = usize;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct IrVariable {
|
pub struct IrVariable {
|
||||||
name: Rc<str>,
|
name: Rc<str>,
|
||||||
type_info: IrTypeInfo,
|
type_info: IrTypeInfo,
|
||||||
|
|||||||
@ -34,6 +34,7 @@ pub struct LowerToIrResult {
|
|||||||
pub functions: Vec<IrFunction>,
|
pub functions: Vec<IrFunction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct LowerToIrContext<'a> {
|
struct LowerToIrContext<'a> {
|
||||||
symbols: &'a [Symbol],
|
symbols: &'a [Symbol],
|
||||||
nodes_to_symbols: &'a HashMap<NodeId, SymbolId>,
|
nodes_to_symbols: &'a HashMap<NodeId, SymbolId>,
|
||||||
@ -104,6 +105,7 @@ pub fn lower_to_ir_synthetic_function(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct LowerToIrFunctionContext {
|
struct LowerToIrFunctionContext {
|
||||||
blocks: Vec<IrBlock>,
|
blocks: Vec<IrBlock>,
|
||||||
ir_variables: Vec<IrVariable>,
|
ir_variables: Vec<IrVariable>,
|
||||||
@ -463,6 +465,7 @@ fn lower_expression_to_ir_expression(
|
|||||||
{
|
{
|
||||||
IrExpression::Parameter(*rhs_ir_parameter_id)
|
IrExpression::Parameter(*rhs_ir_parameter_id)
|
||||||
} else {
|
} else {
|
||||||
|
println!("Dump:\n{:#?}\n{:#?}", ctx, fn_ctx);
|
||||||
panic!(
|
panic!(
|
||||||
"Could not find parameter or variable for symbol_id {}",
|
"Could not find parameter or variable for symbol_id {}",
|
||||||
rhs_symbol_id
|
rhs_symbol_id
|
||||||
|
|||||||
@ -44,9 +44,9 @@ pub struct AnalysisContext {
|
|||||||
impl AnalysisContext {
|
impl AnalysisContext {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
root_scope_id: 0, // pushed in vec! below
|
||||||
scopes: vec![Scope::new(None)],
|
scopes: vec![Scope::new(None)],
|
||||||
nodes_to_scopes: HashMap::new(),
|
nodes_to_scopes: HashMap::new(),
|
||||||
root_scope_id: 0, // already pushed in vec! above
|
|
||||||
symbols: Vec::new(),
|
symbols: Vec::new(),
|
||||||
nodes_to_symbols: HashMap::new(),
|
nodes_to_symbols: HashMap::new(),
|
||||||
type_infos: Vec::new(),
|
type_infos: Vec::new(),
|
||||||
@ -55,6 +55,18 @@ impl AnalysisContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn root_scope_id(&self) -> ScopeId {
|
||||||
|
self.root_scope_id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn scopes(&self) -> &[Scope] {
|
||||||
|
&self.scopes
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn scopes_mut(&mut self) -> &mut Vec<Scope> {
|
||||||
|
&mut self.scopes
|
||||||
|
}
|
||||||
|
|
||||||
pub fn symbols(&self) -> &[Symbol] {
|
pub fn symbols(&self) -> &[Symbol] {
|
||||||
&self.symbols
|
&self.symbols
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
pub type SymbolId = usize;
|
pub type SymbolId = usize;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Symbol {
|
pub enum Symbol {
|
||||||
Function(FunctionSymbol),
|
Function(FunctionSymbol),
|
||||||
Parameter(ParameterSymbol),
|
Parameter(ParameterSymbol),
|
||||||
@ -35,6 +36,7 @@ impl Symbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct FunctionSymbol {
|
pub struct FunctionSymbol {
|
||||||
declared_name: Rc<str>,
|
declared_name: Rc<str>,
|
||||||
declared_name_source_range: Option<SourceRange>,
|
declared_name_source_range: Option<SourceRange>,
|
||||||
@ -82,6 +84,7 @@ impl FunctionSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ParameterSymbol {
|
pub struct ParameterSymbol {
|
||||||
name: Rc<str>,
|
name: Rc<str>,
|
||||||
source_range: Option<SourceRange>,
|
source_range: Option<SourceRange>,
|
||||||
@ -105,6 +108,7 @@ impl ParameterSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct VariableSymbol {
|
pub struct VariableSymbol {
|
||||||
name: Rc<str>,
|
name: Rc<str>,
|
||||||
source_range: Option<SourceRange>,
|
source_range: Option<SourceRange>,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::fmt::{Display, Formatter};
|
|||||||
|
|
||||||
pub type TypeInfoId = usize;
|
pub type TypeInfoId = usize;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum TypeInfo {
|
pub enum TypeInfo {
|
||||||
Any,
|
Any,
|
||||||
Function(FunctionTypeInfo),
|
Function(FunctionTypeInfo),
|
||||||
@ -31,7 +31,7 @@ impl Display for TypeInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct FunctionTypeInfo {
|
pub struct FunctionTypeInfo {
|
||||||
parameter_type_info_ids: Vec<TypeInfoId>,
|
parameter_type_info_ids: Vec<TypeInfoId>,
|
||||||
return_type_info_id: TypeInfoId,
|
return_type_info_id: TypeInfoId,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user