Implement codegen for structs
This commit is contained in:
		
							parent
							
								
									d1a37058df
								
							
						
					
					
						commit
						2a879b5ef4
					
				@ -201,10 +201,6 @@ impl ModuleHolder {
 | 
				
			|||||||
                context.context_ref,
 | 
					                context.context_ref,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for _ty in &self.types {
 | 
					 | 
				
			||||||
                todo!("Do something with types!");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Compile the contents
 | 
					            // Compile the contents
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let mut types = HashMap::new();
 | 
					            let mut types = HashMap::new();
 | 
				
			||||||
 | 
				
			|||||||
@ -288,4 +288,4 @@ pub enum CustomTypeKind {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
 | 
					#[derive(Debug, PartialEq, Eq, Clone, Hash)]
 | 
				
			||||||
pub struct NamedStruct(String, Vec<Type>);
 | 
					pub struct NamedStruct(pub String, pub Vec<Type>);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,16 @@
 | 
				
			|||||||
use std::{collections::HashMap, mem};
 | 
					use std::{collections::HashMap, mem};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use reid_lib::{
 | 
					use reid_lib::{
 | 
				
			||||||
    builder::InstructionValue, compile::CompiledModule, Block, CmpPredicate, ConstValue, Context,
 | 
					    builder::{InstructionValue, TypeValue},
 | 
				
			||||||
    Function, FunctionFlags, Instr, Module, TerminatorKind as Term, Type,
 | 
					    compile::CompiledModule,
 | 
				
			||||||
 | 
					    Block, CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr,
 | 
				
			||||||
 | 
					    Module, NamedStruct, TerminatorKind as Term, Type,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::mir::{self, types::ReturnType, IndexedVariableReference, NamedVariableRef, TypeKind};
 | 
					use crate::mir::{
 | 
				
			||||||
 | 
					    self, types::ReturnType, IndexedVariableReference, NamedVariableRef, StructType,
 | 
				
			||||||
 | 
					    TypeDefinitionKind, TypeKind,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Context that contains all of the given modules as complete codegenerated
 | 
					/// Context that contains all of the given modules as complete codegenerated
 | 
				
			||||||
/// LLIR that can then be finally compiled into LLVM IR.
 | 
					/// LLIR that can then be finally compiled into LLVM IR.
 | 
				
			||||||
@ -47,20 +52,42 @@ impl mir::Module {
 | 
				
			|||||||
    fn codegen<'ctx>(&self, context: &'ctx Context) -> ModuleCodegen<'ctx> {
 | 
					    fn codegen<'ctx>(&self, context: &'ctx Context) -> ModuleCodegen<'ctx> {
 | 
				
			||||||
        let mut module = context.module(&self.name, self.is_main);
 | 
					        let mut module = context.module(&self.name, self.is_main);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut types = HashMap::new();
 | 
				
			||||||
 | 
					        let mut type_values = HashMap::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for typedef in &self.typedefs {
 | 
				
			||||||
 | 
					            let type_value = match &typedef.kind {
 | 
				
			||||||
 | 
					                TypeDefinitionKind::Struct(StructType(fields)) => {
 | 
				
			||||||
 | 
					                    module.custom_type(CustomTypeKind::NamedStruct(NamedStruct(
 | 
				
			||||||
 | 
					                        typedef.name.clone(),
 | 
				
			||||||
 | 
					                        fields
 | 
				
			||||||
 | 
					                            .iter()
 | 
				
			||||||
 | 
					                            // TODO: Reorder custom-type definitions such that
 | 
				
			||||||
 | 
					                            // inner types get evaluated first. Otherwise this
 | 
				
			||||||
 | 
					                            // will cause a panic!
 | 
				
			||||||
 | 
					                            .map(|(_, t)| t.get_type(&type_values))
 | 
				
			||||||
 | 
					                            .collect(),
 | 
				
			||||||
 | 
					                    )))
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            types.insert(type_value, typedef.kind.clone());
 | 
				
			||||||
 | 
					            type_values.insert(typedef.name.clone(), type_value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut functions = HashMap::new();
 | 
					        let mut functions = HashMap::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for function in &self.functions {
 | 
					        for function in &self.functions {
 | 
				
			||||||
            let param_types: Vec<Type> = function
 | 
					            let param_types: Vec<Type> = function
 | 
				
			||||||
                .parameters
 | 
					                .parameters
 | 
				
			||||||
                .iter()
 | 
					                .iter()
 | 
				
			||||||
                .map(|(_, p)| p.get_type())
 | 
					                .map(|(_, p)| p.get_type(&type_values))
 | 
				
			||||||
                .collect();
 | 
					                .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let is_main = self.is_main && function.name == "main";
 | 
					            let is_main = self.is_main && function.name == "main";
 | 
				
			||||||
            let func = match &function.kind {
 | 
					            let func = match &function.kind {
 | 
				
			||||||
                mir::FunctionDefinitionKind::Local(_, _) => module.function(
 | 
					                mir::FunctionDefinitionKind::Local(_, _) => module.function(
 | 
				
			||||||
                    &function.name,
 | 
					                    &function.name,
 | 
				
			||||||
                    function.return_type.get_type(),
 | 
					                    function.return_type.get_type(&type_values),
 | 
				
			||||||
                    param_types,
 | 
					                    param_types,
 | 
				
			||||||
                    FunctionFlags {
 | 
					                    FunctionFlags {
 | 
				
			||||||
                        is_pub: function.is_pub || is_main,
 | 
					                        is_pub: function.is_pub || is_main,
 | 
				
			||||||
@ -71,7 +98,7 @@ impl mir::Module {
 | 
				
			|||||||
                ),
 | 
					                ),
 | 
				
			||||||
                mir::FunctionDefinitionKind::Extern(imported) => module.function(
 | 
					                mir::FunctionDefinitionKind::Extern(imported) => module.function(
 | 
				
			||||||
                    &function.name,
 | 
					                    &function.name,
 | 
				
			||||||
                    function.return_type.get_type(),
 | 
					                    function.return_type.get_type(&type_values),
 | 
				
			||||||
                    param_types,
 | 
					                    param_types,
 | 
				
			||||||
                    FunctionFlags {
 | 
					                    FunctionFlags {
 | 
				
			||||||
                        is_extern: true,
 | 
					                        is_extern: true,
 | 
				
			||||||
@ -93,7 +120,7 @@ impl mir::Module {
 | 
				
			|||||||
                    p_name.clone(),
 | 
					                    p_name.clone(),
 | 
				
			||||||
                    StackValue(
 | 
					                    StackValue(
 | 
				
			||||||
                        StackValueKind::Immutable(entry.build(Instr::Param(i)).unwrap()),
 | 
					                        StackValueKind::Immutable(entry.build(Instr::Param(i)).unwrap()),
 | 
				
			||||||
                        p_ty.get_type(),
 | 
					                        p_ty.get_type(&type_values),
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -104,6 +131,8 @@ impl mir::Module {
 | 
				
			|||||||
                function,
 | 
					                function,
 | 
				
			||||||
                block: entry,
 | 
					                block: entry,
 | 
				
			||||||
                functions: &functions,
 | 
					                functions: &functions,
 | 
				
			||||||
 | 
					                types: &types,
 | 
				
			||||||
 | 
					                type_values: &type_values,
 | 
				
			||||||
                stack_values,
 | 
					                stack_values,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            match &mir_function.kind {
 | 
					            match &mir_function.kind {
 | 
				
			||||||
@ -131,6 +160,8 @@ pub struct Scope<'ctx, 'a> {
 | 
				
			|||||||
    module: &'ctx Module<'ctx>,
 | 
					    module: &'ctx Module<'ctx>,
 | 
				
			||||||
    function: &'ctx Function<'ctx>,
 | 
					    function: &'ctx Function<'ctx>,
 | 
				
			||||||
    block: Block<'ctx>,
 | 
					    block: Block<'ctx>,
 | 
				
			||||||
 | 
					    types: &'a HashMap<TypeValue, TypeDefinitionKind>,
 | 
				
			||||||
 | 
					    type_values: &'a HashMap<String, TypeValue>,
 | 
				
			||||||
    functions: &'a HashMap<String, Function<'ctx>>,
 | 
					    functions: &'a HashMap<String, Function<'ctx>>,
 | 
				
			||||||
    stack_values: HashMap<String, StackValue>,
 | 
					    stack_values: HashMap<String, StackValue>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -152,6 +183,8 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
 | 
				
			|||||||
            context: self.context,
 | 
					            context: self.context,
 | 
				
			||||||
            module: self.module,
 | 
					            module: self.module,
 | 
				
			||||||
            functions: self.functions,
 | 
					            functions: self.functions,
 | 
				
			||||||
 | 
					            types: self.types,
 | 
				
			||||||
 | 
					            type_values: self.type_values,
 | 
				
			||||||
            stack_values: self.stack_values.clone(),
 | 
					            stack_values: self.stack_values.clone(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -163,6 +196,10 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
 | 
				
			|||||||
        mem::swap(&mut self.block, &mut old_block);
 | 
					        mem::swap(&mut self.block, &mut old_block);
 | 
				
			||||||
        old_block
 | 
					        old_block
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn get_typedef(&self, name: &String) -> Option<&TypeDefinitionKind> {
 | 
				
			||||||
 | 
					        self.type_values.get(name).and_then(|v| self.types.get(v))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl IndexedVariableReference {
 | 
					impl IndexedVariableReference {
 | 
				
			||||||
@ -184,8 +221,24 @@ impl IndexedVariableReference {
 | 
				
			|||||||
                    _ => panic!("Tried to codegen indexing a non-indexable value!"),
 | 
					                    _ => panic!("Tried to codegen indexing a non-indexable value!"),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            mir::IndexedVariableReferenceKind::StructIndex(indexed_variable_reference, _) => {
 | 
					            mir::IndexedVariableReferenceKind::StructIndex(inner, field) => {
 | 
				
			||||||
                todo!("codegen for indexed var refrence")
 | 
					                let (inner_val, mut indices) = inner.get_stack_value(scope)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let idx = if let Type::CustomType(ty_val) = inner_val.1 {
 | 
				
			||||||
 | 
					                    match scope.types.get(&ty_val).unwrap() {
 | 
				
			||||||
 | 
					                        TypeDefinitionKind::Struct(struct_type) => struct_type.find_index(field),
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    None
 | 
				
			||||||
 | 
					                }?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                match &inner_val.1 {
 | 
				
			||||||
 | 
					                    Type::Ptr(_) => {
 | 
				
			||||||
 | 
					                        indices.push(idx as u32);
 | 
				
			||||||
 | 
					                        Some((inner_val, indices))
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    _ => panic!("Tried to codegen indexing a non-indexable value!"),
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -206,14 +259,17 @@ impl mir::Statement {
 | 
				
			|||||||
                                _ => StackValueKind::Mutable({
 | 
					                                _ => StackValueKind::Mutable({
 | 
				
			||||||
                                    let alloca = scope
 | 
					                                    let alloca = scope
 | 
				
			||||||
                                        .block
 | 
					                                        .block
 | 
				
			||||||
                                        .build(Instr::Alloca(name.clone(), ty.get_type()))
 | 
					                                        .build(Instr::Alloca(
 | 
				
			||||||
 | 
					                                            name.clone(),
 | 
				
			||||||
 | 
					                                            ty.get_type(scope.type_values),
 | 
				
			||||||
 | 
					                                        ))
 | 
				
			||||||
                                        .unwrap();
 | 
					                                        .unwrap();
 | 
				
			||||||
                                    scope.block.build(Instr::Store(alloca, value)).unwrap();
 | 
					                                    scope.block.build(Instr::Store(alloca, value)).unwrap();
 | 
				
			||||||
                                    alloca
 | 
					                                    alloca
 | 
				
			||||||
                                }),
 | 
					                                }),
 | 
				
			||||||
                            },
 | 
					                            },
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                        ty.get_type(),
 | 
					                        ty.get_type(scope.type_values),
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
                None
 | 
					                None
 | 
				
			||||||
@ -398,7 +454,7 @@ impl mir::Expression {
 | 
				
			|||||||
                Some(
 | 
					                Some(
 | 
				
			||||||
                    scope
 | 
					                    scope
 | 
				
			||||||
                        .block
 | 
					                        .block
 | 
				
			||||||
                        .build(Instr::Load(ptr, val_t.get_type()))
 | 
					                        .build(Instr::Load(ptr, val_t.get_type(scope.type_values)))
 | 
				
			||||||
                        .unwrap(),
 | 
					                        .unwrap(),
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -416,7 +472,7 @@ impl mir::Expression {
 | 
				
			|||||||
                let array = scope
 | 
					                let array = scope
 | 
				
			||||||
                    .block
 | 
					                    .block
 | 
				
			||||||
                    .build(Instr::ArrayAlloca(
 | 
					                    .build(Instr::ArrayAlloca(
 | 
				
			||||||
                        instr_t.get_type(),
 | 
					                        instr_t.get_type(scope.type_values),
 | 
				
			||||||
                        instr_list.len() as u32,
 | 
					                        instr_list.len() as u32,
 | 
				
			||||||
                    ))
 | 
					                    ))
 | 
				
			||||||
                    .unwrap();
 | 
					                    .unwrap();
 | 
				
			||||||
@ -431,10 +487,49 @@ impl mir::Expression {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                Some(array)
 | 
					                Some(array)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            mir::ExprKind::StructIndex(expression, type_kind, _) => {
 | 
					            mir::ExprKind::StructIndex(expression, type_kind, field) => {
 | 
				
			||||||
                todo!("codegen for struct index")
 | 
					                let struct_val = expression.codegen(scope)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let struct_ty = expression.return_type().ok()?.1.known().ok()?;
 | 
				
			||||||
 | 
					                let TypeKind::CustomType(name) = struct_ty else {
 | 
				
			||||||
 | 
					                    return None;
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                let TypeDefinitionKind::Struct(struct_ty) = scope.get_typedef(&name)?;
 | 
				
			||||||
 | 
					                let idx = struct_ty.find_index(field)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let ptr = scope
 | 
				
			||||||
 | 
					                    .block
 | 
				
			||||||
 | 
					                    .build(Instr::GetStructElemPtr(struct_val, idx as u32))
 | 
				
			||||||
 | 
					                    .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Some(
 | 
				
			||||||
 | 
					                    scope
 | 
				
			||||||
 | 
					                        .block
 | 
				
			||||||
 | 
					                        .build(Instr::Load(ptr, type_kind.get_type(scope.type_values)))
 | 
				
			||||||
 | 
					                        .unwrap(),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            mir::ExprKind::Struct(name, items) => {
 | 
				
			||||||
 | 
					                let struct_ptr = scope
 | 
				
			||||||
 | 
					                    .block
 | 
				
			||||||
 | 
					                    .build(Instr::Alloca(
 | 
				
			||||||
 | 
					                        name.clone(),
 | 
				
			||||||
 | 
					                        Type::CustomType(*scope.type_values.get(name)?),
 | 
				
			||||||
 | 
					                    ))
 | 
				
			||||||
 | 
					                    .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (i, (_, exp)) in items.iter().enumerate() {
 | 
				
			||||||
 | 
					                    let elem_ptr = scope
 | 
				
			||||||
 | 
					                        .block
 | 
				
			||||||
 | 
					                        .build(Instr::GetStructElemPtr(struct_ptr, i as u32))
 | 
				
			||||||
 | 
					                        .unwrap();
 | 
				
			||||||
 | 
					                    if let Some(val) = exp.codegen(scope) {
 | 
				
			||||||
 | 
					                        scope.block.build(Instr::Store(elem_ptr, val)).unwrap();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Some(struct_ptr)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            mir::ExprKind::Struct(_, items) => todo!("codegen for struct expression"),
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -501,7 +596,7 @@ impl mir::Literal {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl TypeKind {
 | 
					impl TypeKind {
 | 
				
			||||||
    fn get_type(&self) -> Type {
 | 
					    fn get_type(&self, type_vals: &HashMap<String, TypeValue>) -> Type {
 | 
				
			||||||
        match &self {
 | 
					        match &self {
 | 
				
			||||||
            TypeKind::I8 => Type::I8,
 | 
					            TypeKind::I8 => Type::I8,
 | 
				
			||||||
            TypeKind::I16 => Type::I16,
 | 
					            TypeKind::I16 => Type::I16,
 | 
				
			||||||
@ -515,10 +610,10 @@ impl TypeKind {
 | 
				
			|||||||
            TypeKind::U128 => Type::U128,
 | 
					            TypeKind::U128 => Type::U128,
 | 
				
			||||||
            TypeKind::Bool => Type::Bool,
 | 
					            TypeKind::Bool => Type::Bool,
 | 
				
			||||||
            TypeKind::StringPtr => Type::Ptr(Box::new(Type::I8)),
 | 
					            TypeKind::StringPtr => Type::Ptr(Box::new(Type::I8)),
 | 
				
			||||||
            TypeKind::Array(elem_t, _) => Type::Ptr(Box::new(elem_t.get_type())),
 | 
					            TypeKind::Array(elem_t, _) => Type::Ptr(Box::new(elem_t.get_type(type_vals))),
 | 
				
			||||||
            TypeKind::Void => Type::Void,
 | 
					            TypeKind::Void => Type::Void,
 | 
				
			||||||
            TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
 | 
					            TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
 | 
				
			||||||
            TypeKind::CustomType(_) => todo!("codegen for custom type"),
 | 
					            TypeKind::CustomType(n) => Type::CustomType(type_vals.get(n).unwrap().clone()),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -84,6 +84,16 @@ pub enum VagueType {
 | 
				
			|||||||
#[derive(Clone, Debug)]
 | 
					#[derive(Clone, Debug)]
 | 
				
			||||||
pub struct StructType(pub Vec<(String, TypeKind)>);
 | 
					pub struct StructType(pub Vec<(String, TypeKind)>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl StructType {
 | 
				
			||||||
 | 
					    pub fn find_index(&self, name: &String) -> Option<u32> {
 | 
				
			||||||
 | 
					        self.0
 | 
				
			||||||
 | 
					            .iter()
 | 
				
			||||||
 | 
					            .enumerate()
 | 
				
			||||||
 | 
					            .find(|(_, (n, _))| n == name)
 | 
				
			||||||
 | 
					            .map(|(i, _)| i as u32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type TypedefMap = HashMap<String, TypeDefinitionKind>;
 | 
					pub type TypedefMap = HashMap<String, TypeDefinitionKind>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl TypeKind {
 | 
					impl TypeKind {
 | 
				
			||||||
 | 
				
			|||||||
@ -300,7 +300,7 @@ impl Statement {
 | 
				
			|||||||
            StmtKind::Set(_, expression) => {
 | 
					            StmtKind::Set(_, expression) => {
 | 
				
			||||||
                expression.pass(pass, state, scope);
 | 
					                expression.pass(pass, state, scope);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            StmtKind::Import(_) => todo!(),
 | 
					            StmtKind::Import(_) => {} // Never exists at this stage
 | 
				
			||||||
            StmtKind::Expression(expression) => {
 | 
					            StmtKind::Expression(expression) => {
 | 
				
			||||||
                expression.pass(pass, state, scope);
 | 
					                expression.pass(pass, state, scope);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -322,7 +322,7 @@ impl Statement {
 | 
				
			|||||||
                    .ok();
 | 
					                    .ok();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            StmtKind::Set(_, _) => {}
 | 
					            StmtKind::Set(_, _) => {}
 | 
				
			||||||
            StmtKind::Import(_) => todo!(),
 | 
					            StmtKind::Import(_) => {} // Never exists at this stage
 | 
				
			||||||
            StmtKind::Expression(_) => {}
 | 
					            StmtKind::Expression(_) => {}
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user