forked from M-Labs/nac3
use alloca for variables
This commit is contained in:
parent
c5efa615a2
commit
f9dbf68875
17
src/main.rs
17
src/main.rs
|
@ -73,7 +73,7 @@ struct CodeGen<'ctx> {
|
||||||
module: Module<'ctx>,
|
module: Module<'ctx>,
|
||||||
builder: Builder<'ctx>,
|
builder: Builder<'ctx>,
|
||||||
current_source_location: ast::Location,
|
current_source_location: ast::Location,
|
||||||
namespace: HashMap<String, values::BasicValueEnum<'ctx>>,
|
namespace: HashMap<String, values::PointerValue<'ctx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> CodeGen<'ctx> {
|
impl<'ctx> CodeGen<'ctx> {
|
||||||
|
@ -165,7 +165,10 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
self.builder.position_at_end(basic_block);
|
self.builder.position_at_end(basic_block);
|
||||||
|
|
||||||
for (n, arg) in args.args.iter().enumerate() {
|
for (n, arg) in args.args.iter().enumerate() {
|
||||||
self.namespace.insert(arg.arg.clone(), function.get_nth_param(n as u32).unwrap());
|
let param = function.get_nth_param(n as u32).unwrap();
|
||||||
|
let alloca = self.builder.build_alloca(param.get_type(), &arg.arg);
|
||||||
|
self.builder.build_store(alloca, param);
|
||||||
|
self.namespace.insert(arg.arg.clone(), alloca);
|
||||||
}
|
}
|
||||||
|
|
||||||
for statement in body.iter() {
|
for statement in body.iter() {
|
||||||
|
@ -197,7 +200,7 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
},
|
},
|
||||||
ast::ExpressionType::Identifier { name } => {
|
ast::ExpressionType::Identifier { name } => {
|
||||||
match self.namespace.get(name) {
|
match self.namespace.get(name) {
|
||||||
Some(value) => Ok(*value),
|
Some(value) => Ok(self.builder.build_load(*value, name).into()),
|
||||||
None => Err(self.compile_error(CompileErrorKind::UnboundIdentifier))
|
None => Err(self.compile_error(CompileErrorKind::UnboundIdentifier))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -370,11 +373,13 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
for target in targets.iter() {
|
for target in targets.iter() {
|
||||||
self.set_source_location(target.location);
|
self.set_source_location(target.location);
|
||||||
if let ast::ExpressionType::Identifier { name } = &target.node {
|
if let ast::ExpressionType::Identifier { name } = &target.node {
|
||||||
if let Some(existing) = self.namespace.insert(name.clone(), value) {
|
let builder = &self.builder;
|
||||||
if existing.get_type() != value.get_type() {
|
let target = self.namespace.entry(name.clone()).or_insert_with(
|
||||||
|
|| builder.build_alloca(value.get_type(), name));
|
||||||
|
if target.get_type() != value.get_type().ptr_type(inkwell::AddressSpace::Generic) {
|
||||||
return Err(self.compile_error(CompileErrorKind::IncompatibleTypes));
|
return Err(self.compile_error(CompileErrorKind::IncompatibleTypes));
|
||||||
}
|
}
|
||||||
}
|
builder.build_store(*target, value);
|
||||||
} else {
|
} else {
|
||||||
return Err(self.compile_error(CompileErrorKind::Unsupported("assignment target must be an identifier")))
|
return Err(self.compile_error(CompileErrorKind::Unsupported("assignment target must be an identifier")))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue