Skip to content

Commit cc6cc4d

Browse files
authored
Fix global variables (#67)
1 parent cfea7c3 commit cc6cc4d

File tree

5 files changed

+118
-74
lines changed

5 files changed

+118
-74
lines changed

src/compiler/mod.rs

Lines changed: 91 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -495,22 +495,6 @@ impl Visitor<Value> for Compiler {
495495
}
496496
}
497497
}
498-
Some(Value::Pending) => {
499-
let args: Vec<llvm::Value> = expr
500-
.args
501-
.iter()
502-
.map(|arg| match self.walk(arg) {
503-
Value::Numeric(n) => n,
504-
_ => todo!("{:?}", self.walk(arg)),
505-
})
506-
.collect();
507-
508-
Value::Numeric(self.builder.build_call(
509-
&self.stack.last().unwrap().fun,
510-
&args,
511-
literal,
512-
))
513-
}
514498
Some(e) => panic!("unexpected {:?}", e),
515499
None => panic!("undefined function {}", literal),
516500
},
@@ -674,7 +658,6 @@ impl Compiler {
674658
fn set_var(&mut self, literal: &str, val: Value) {
675659
let typ = match val {
676660
Value::Numeric(_) => self.context.double_type(),
677-
Value::Pending => self.context.void_type(),
678661
Value::Vec(_) => self.context.double_type().pointer_type(0),
679662
Value::Null => self.context.void_type(),
680663
Value::String(_) => self.context.i8_type().pointer_type(0),
@@ -695,43 +678,99 @@ impl Compiler {
695678
},
696679
None => None,
697680
};
681+
if self.get_var(literal).is_none() && self.stack.len() <= 1 {
682+
let ptr = match val {
683+
Value::Null => unreachable!(),
684+
Value::Numeric(_)
685+
| Value::String(_)
686+
| Value::GlobalString(_)
687+
| Value::Vec(_)
688+
| Value::Bool(_) => self.module.add_global(typ, literal),
689+
Value::Function { val: v, .. } => v,
690+
};
698691

699-
let ptr = existing_ptr.unwrap_or_else(|| self.builder.build_alloca(typ, literal));
700-
701-
let var = match val {
702-
Value::Numeric(_) => Var::Numeric(ptr),
703-
Value::Pending => Var::Pending,
704-
Value::Null => Var::Null,
705-
Value::String(_) => Var::String(ptr),
706-
Value::GlobalString(_) => Var::GlobalString(ptr),
707-
Value::Vec(_) => Var::Vec(ptr),
708-
Value::Bool(_) => Var::Bool(ptr),
709-
Value::Function {
710-
typ,
711-
return_type,
712-
val,
713-
..
714-
} => Var::Function {
715-
val,
716-
typ,
717-
return_type,
718-
},
719-
};
692+
match val {
693+
Value::Numeric(_) | Value::GlobalString(_) | Value::Vec(_) => {
694+
ptr.set_initializer(self.context.const_double(0.0));
695+
}
696+
Value::Null => unreachable!(),
697+
Value::String(_) => todo!(),
698+
Value::Function { .. } => (),
699+
Value::Bool(_) => {
700+
ptr.set_initializer(self.context.const_bool(false));
701+
}
702+
}
720703

721-
self.stack
722-
.last_mut()
723-
.unwrap()
724-
.set(&self.context, &self.builder, literal, var);
725-
726-
match val {
727-
Value::Numeric(v)
728-
| Value::String(v)
729-
| Value::GlobalString(v)
730-
| Value::Vec(v)
731-
| Value::Bool(v) => self.builder.create_store(v, &ptr),
732-
Value::Function { val: v, .. } => v,
733-
_ => todo!("{:?}", val),
734-
};
704+
let var = match val {
705+
Value::Numeric(_) => Var::Numeric(ptr),
706+
Value::Null => Var::Null,
707+
Value::String(_) => Var::String(ptr),
708+
Value::GlobalString(_) => Var::GlobalString(ptr),
709+
Value::Vec(_) => Var::Vec(ptr),
710+
Value::Bool(_) => Var::Bool(ptr),
711+
Value::Function {
712+
typ,
713+
return_type,
714+
val,
715+
..
716+
} => Var::Function {
717+
val,
718+
typ,
719+
return_type,
720+
},
721+
};
722+
723+
self.stack
724+
.last_mut()
725+
.unwrap()
726+
.set(&self.context, &self.builder, literal, var);
727+
728+
match val {
729+
Value::Numeric(v)
730+
| Value::String(v)
731+
| Value::GlobalString(v)
732+
| Value::Vec(v)
733+
| Value::Bool(v) => self.builder.create_store(v, &ptr),
734+
Value::Function { val: v, .. } => v,
735+
_ => todo!("{:?}", val),
736+
};
737+
} else {
738+
let ptr = existing_ptr.unwrap_or_else(|| self.builder.build_alloca(typ, literal));
739+
740+
let var = match val {
741+
Value::Numeric(_) => Var::Numeric(ptr),
742+
Value::Null => Var::Null,
743+
Value::String(_) => Var::String(ptr),
744+
Value::GlobalString(_) => Var::GlobalString(ptr),
745+
Value::Vec(_) => Var::Vec(ptr),
746+
Value::Bool(_) => Var::Bool(ptr),
747+
Value::Function {
748+
typ,
749+
return_type,
750+
val,
751+
..
752+
} => Var::Function {
753+
val,
754+
typ,
755+
return_type,
756+
},
757+
};
758+
759+
self.stack
760+
.last_mut()
761+
.unwrap()
762+
.set(&self.context, &self.builder, literal, var);
763+
764+
match val {
765+
Value::Numeric(v)
766+
| Value::String(v)
767+
| Value::GlobalString(v)
768+
| Value::Vec(v)
769+
| Value::Bool(v) => self.builder.create_store(v, &ptr),
770+
Value::Function { val: v, .. } => v,
771+
_ => todo!("{:?}", val),
772+
};
773+
}
735774
}
736775

737776
#[allow(dead_code)]

src/compiler/value.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,4 @@ pub enum Value {
1414
return_type: parser::Type,
1515
},
1616
Vec(llvm::Value),
17-
Pending,
1817
}

src/compiler/var.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::parser;
44
#[derive(Debug, Clone, Copy)]
55
pub enum Var {
66
Numeric(llvm::Value),
7-
Pending,
87
Null,
98
String(llvm::Value),
109
Vec(llvm::Value),

src/llvm/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ impl Value {
229229
Err(Box::new(LLVMError {}))
230230
}
231231
}
232+
233+
pub fn set_initializer(&self, value: Value) {
234+
unsafe {
235+
LLVMSetInitializer(self.0, value.0);
236+
}
237+
}
232238
}
233239

234240
pub struct Module(*mut llvm::LLVMModule);
@@ -243,6 +249,10 @@ impl Module {
243249
}
244250
}
245251

252+
pub fn add_global(&self, typ: Type, name: &str) -> Value {
253+
Value(unsafe { LLVMAddGlobal(self.0, typ.0, c_str(name).as_ptr()) })
254+
}
255+
246256
pub fn add_function(&self, name: &str, function_type: Type) -> Value {
247257
Value(unsafe { LLVMAddFunction(self.0, c_str(name).as_ptr(), function_type.0) })
248258
}

tests/compiler_tests.rs

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,13 @@ fn it_compiles_numeric_asignment() {
2525
remove_whitespace(&compiler.ir_string()),
2626
remove_whitespace(
2727
"
28-
; ModuleID = 'main'\nsource_filename = \"main\"
29-
target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\"
30-
31-
define void @__main__() {
32-
entry:
33-
%x = alloca double, align 8
34-
store double 5.000000e+00, double* %x , align 8
35-
ret void
36-
}
28+
;ModuleID='main'source_filename=\"main\"targetdatalayout=\"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\"
29+
@x= global double 0.000000e+00
30+
define void @__main__() {
31+
entry:
32+
store double 5.000000e+00, double*@x, align 8
33+
ret void
34+
}
3735
"
3836
)
3937
);
@@ -62,17 +60,16 @@ fn it_compiles_numeric_to_numeric_asignment() {
6260
remove_whitespace(&compiler.ir_string()),
6361
remove_whitespace(
6462
"
65-
; ModuleID = 'main'\nsource_filename = \"main\"
66-
target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\"
67-
define void @__main__() {
68-
entry:
69-
%x = alloca double, align 8
70-
store double 5.000000e+00, double* %x , align 8
71-
%0 = loaddouble, double* %x, align 8
72-
%y = alloca double, align 8
73-
store double %0, double* %y, align 8
74-
ret void
75-
}
63+
;ModuleID='main'source_filename=\"main\"targetdatalayout=\"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\"
64+
@x = global double 0.000000e+00
65+
@y = global double 0.000000e+00
66+
define void @__main__() {
67+
entry:
68+
store double 5.000000e+00, double*@x, align 8
69+
%0= load double, double*@x, align 8
70+
store double %0, double* @y, align 8
71+
ret void
72+
}
7673
"
7774
)
7875
);

0 commit comments

Comments
 (0)