@@ -286,11 +286,11 @@ pub struct Prototype {
286
286
pub prec : usize
287
287
}
288
288
289
- /// Defines a user-defined function.
289
+ /// Defines a user-defined or external function.
290
290
#[ derive( Debug ) ]
291
291
pub struct Function {
292
292
pub prototype : Prototype ,
293
- pub body : Expr ,
293
+ pub body : Option < Expr > ,
294
294
pub is_anon : bool
295
295
}
296
296
@@ -502,7 +502,7 @@ impl<'a> Parser<'a> {
502
502
// Return new function
503
503
Ok ( Function {
504
504
prototype : proto,
505
- body : body,
505
+ body : Some ( body) ,
506
506
is_anon : false
507
507
} )
508
508
}
@@ -515,10 +515,9 @@ impl<'a> Parser<'a> {
515
515
// Parse signature of extern function
516
516
let proto = self . parse_prototype ( ) ?;
517
517
518
- // Return signature of extern function
519
518
Ok ( Function {
520
519
prototype : proto,
521
- body : Expr :: Number ( std :: f64 :: NAN ) ,
520
+ body : None ,
522
521
is_anon : false
523
522
} )
524
523
}
@@ -820,8 +819,9 @@ impl<'a> Parser<'a> {
820
819
args : vec ! [ ] ,
821
820
is_op : false ,
822
821
prec : 0
822
+
823
823
} ,
824
- body : expr,
824
+ body : Some ( expr) ,
825
825
is_anon : true
826
826
} )
827
827
} ,
@@ -1114,6 +1114,12 @@ impl<'a> Compiler<'a> {
1114
1114
fn compile_fn ( & mut self ) -> Result < FunctionValue , & ' static str > {
1115
1115
let proto = & self . function . prototype ;
1116
1116
let function = self . compile_prototype ( proto) ?;
1117
+
1118
+ // got external function, returning only compiled prototype
1119
+ if self . function . body . is_none ( ) {
1120
+ return Ok ( function) ;
1121
+ }
1122
+
1117
1123
let entry = self . context . append_basic_block ( & function, "entry" ) ;
1118
1124
1119
1125
self . builder . position_at_end ( & entry) ;
@@ -1134,7 +1140,7 @@ impl<'a> Compiler<'a> {
1134
1140
}
1135
1141
1136
1142
// compile body
1137
- let body = self . compile_expr ( & self . function . body ) ?;
1143
+ let body = self . compile_expr ( self . function . body . as_ref ( ) . unwrap ( ) ) ?;
1138
1144
1139
1145
self . builder . build_return ( Some ( & body) ) ;
1140
1146
@@ -1183,24 +1189,24 @@ macro_rules! print_flush {
1183
1189
} ;
1184
1190
}
1185
1191
1186
- // Greg <6A>: 2017-10-03
1187
- // The two following functions are supposed to be found by the JIT
1188
- // using the 'extern' keyword, but it currently does not work on my machine.
1189
- // I tried using add_symbol, add_global_mapping, and simple extern declaration,
1190
- // but nothing worked.
1191
- // However, extern functions such as cos(x) and sin(x) can be imported without any problem.
1192
- // Other lines related to this program can be found further down.
1193
-
1192
+ #[ no_mangle]
1194
1193
pub extern fn putchard ( x : f64 ) -> f64 {
1195
1194
print_flush ! ( "{}" , x as u8 as char ) ;
1196
1195
x
1197
1196
}
1198
1197
1198
+ #[ no_mangle]
1199
1199
pub extern fn printd ( x : f64 ) -> f64 {
1200
1200
println ! ( "{}" , x) ;
1201
1201
x
1202
+
1202
1203
}
1203
1204
1205
+ // Adding the functions above to a global array,
1206
+ // so Rust compiler won't remove them.
1207
+ #[ used]
1208
+ static EXTERNAL_FNS : [ extern fn ( f64 ) -> f64 ; 2 ] = [ putchard, printd] ;
1209
+
1204
1210
/// Entry point of the program; acts as a REPL.
1205
1211
pub fn main ( ) {
1206
1212
// use self::inkwell::support::add_symbol;
0 commit comments