Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Daan Sprenkels
rsplt
Commits
bfe531b5
Commit
bfe531b5
authored
May 02, 2016
by
Daan Sprenkels
Browse files
infer: nuke remaining polymorphic function code
parent
b1324a72
Pipeline
#1390
passed with stage
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/ast.rs
View file @
bfe531b5
...
...
@@ -2,7 +2,7 @@ use std::cell::{RefCell, RefMut};
use
std
::
fmt
;
use
std
::
rc
::
Rc
;
use
infer
::
{
FunctionSignature
,
FunctionType
,
Type
as
SPLType
}
;
use
infer
::
Type
as
SPLType
;
use
infer
::
ToSPLType
;
use
util
::
Span
;
...
...
@@ -187,15 +187,7 @@ impl ToSPLType for FunType {
fn
to_spl_type
(
&
self
)
->
SPLType
{
let
args
=
self
.args
.iter
()
.map
(|
x
|
Box
::
new
(
x
.to_spl_type
()))
.collect
();
let
ret_type
=
self
.ret
.to_spl_type
();
let
template
=
FunctionSignature
{
args
:
args
,
ret
:
Box
::
new
(
ret_type
),
};
let
function_type
=
FunctionType
{
template
:
template
,
signatures
:
Vec
::
new
(),
};
SPLType
::
Function
(
function_type
)
SPLType
::
Function
(
args
,
Box
::
new
(
ret_type
))
}
}
...
...
src/infer.rs
View file @
bfe531b5
...
...
@@ -50,92 +50,13 @@ pub enum Type {
List
(
Box
<
Type
>
),
Pair
(
Box
<
Type
>
,
Box
<
Type
>
),
Bool
,
Function
(
Function
Type
),
Function
(
Vec
<
Box
<
Type
>>
,
Box
<
Type
>
),
Poly
(
String
),
// only used in polymorfic function templates
// Noop: only used to annotate that this type is not relevant, can be used aa
// a placeholder in temporary (short-lived) types
Noop
,
}
impl
Type
{
pub
fn
is_concrete
(
&
self
)
->
bool
{
match
*
self
{
Type
::
Variable
(
usize
)
=>
false
,
Type
::
Void
=>
true
,
Type
::
Int
=>
true
,
Type
::
Char
=>
true
,
Type
::
List
(
ref
inner
)
=>
inner
.is_concrete
(),
Type
::
Pair
(
ref
fst
,
ref
snd
)
=>
fst
.is_concrete
()
&&
snd
.is_concrete
(),
Type
::
Bool
=>
true
,
Type
::
Function
(
_
)
=>
false
,
Type
::
Poly
(
_
)
=>
false
,
Type
::
Noop
=>
false
,
}
}
pub
fn
replace_poly
(
&
self
,
ident
:
&
str
,
replace_with
:
Type
)
->
Type
{
match
*
self
{
Type
::
Poly
(
ref
x
)
if
x
==
ident
=>
replace_with
,
Type
::
List
(
ref
inner
)
=>
Type
::
List
(
Box
::
new
(
inner
.replace_poly
(
ident
,
replace_with
))),
Type
::
Pair
(
ref
fst
,
ref
snd
)
=>
Type
::
Pair
(
Box
::
new
(
fst
.replace_poly
(
ident
,
replace_with
.clone
())),
Box
::
new
(
snd
.replace_poly
(
ident
,
replace_with
)),
),
_
=>
self
.clone
(),
}
}
}
#[derive(Debug,
PartialEq,
Eq,
Clone,
Hash)]
pub
struct
FunctionType
{
pub
template
:
FunctionSignature
,
pub
signatures
:
Vec
<
FunctionSignature
>
,
}
#[derive(Debug,
PartialEq,
Eq,
Clone,
Hash)]
pub
struct
FunctionSignature
{
pub
args
:
Vec
<
Box
<
Type
>>
,
pub
ret
:
Box
<
Type
>
,
}
impl
FunctionType
{
/// `request_signature` will return true if any inference has happened inside this function
/// If it was possible to find a matching signature, this will be returned.
/// If it was not possible to find a matching signature, this function will return (_, None).
/// This does not mean that an error has occurred, if an error occurs in this function,
/// it will panic.
pub
fn
request_signature
(
&
mut
self
,
act_args
:
Vec
<
Box
<
Type
>>
,
ret
:
Type
)
->
Option
<
FunctionSignature
>
{
// generate a new signature, given the requested signature
// and add it to self.1 (the list of signatures)
let
mut
new_sig_args
=
self
.template.args
.clone
();
let
new_sig_ret
=
self
.template.ret
.clone
();
if
new_sig_args
.len
()
!=
act_args
.len
()
{
panic!
(
"wrong amount of arguments applied to function"
);
}
for
i
in
0
..
new_sig_args
.len
()
{
let
(
mut
sig_arg
,
mut
act_arg
)
=
(
*
new_sig_args
[
i
]
.clone
(),
*
act_args
[
i
]
.clone
());
if
let
Some
((
x
,
y
,
polybinds
))
=
try_unification
(
sig_arg
,
act_arg
)
{
new_sig_args
[
i
]
=
Box
::
new
(
x
);
// we now have to update all following arguments to have the unified poly types
for
(
name
,
t
)
in
polybinds
{
for
j
in
i
..
new_sig_args
.len
()
{
let
sig_arg
=
new_sig_args
[
j
]
.clone
();
new_sig_args
[
j
]
=
Box
::
new
(
sig_arg
.replace_poly
(
&
name
,
t
.clone
()));
}
}
}
else
{
// we do not have enough information to unify the function type with the
// requested argument types
return
None
;
}
}
Some
(
FunctionSignature
{
args
:
new_sig_args
,
ret
:
new_sig_ret
,
})
}
}
// unification of free variables and inference
impl
ast
::
SPL
{
...
...
@@ -192,9 +113,6 @@ impl ast::VarDecl {
impl
ast
::
FunDecl
{
pub
fn
unify_free_variables
(
&
mut
self
,
spl
:
&
ast
::
SPL
)
{
let
fun_decl
=
self
.clone
();
if
let
Some
(
ref
mut
fun_type
)
=
self
.fun_type
{
fun_type
.unify_free_type_variables
(
&
fun_decl
);
}
for
vars
in
self
.vars
.iter_mut
()
{
vars
.unify_free_variables
(
spl
,
None
);
}
...
...
@@ -216,13 +134,7 @@ impl ast::FunDecl {
}
impl
ast
::
FunType
{
pub
fn
unify_free_type_variables
(
&
mut
self
,
fun_decl
:
&
ast
::
FunDecl
)
{
for
(
i
,
arg
)
in
self
.args
.iter_mut
()
.enumerate
()
{
if
let
&
mut
ast
::
Type
::
Ident
(
ref
mut
ident
)
=
arg
{
ident
.unify_free_type_variables
(
fun_decl
,
Some
(
i
));
}
}
}
}
impl
ast
::
Stmt
{
...
...
@@ -532,19 +444,6 @@ impl ast::Ident {
panic!
(
"referencing undeclared variable `{}`"
,
self
)
}
}
pub
fn
unify_free_type_variables
(
&
mut
self
,
fun_decl
:
&
ast
::
FunDecl
,
until_fun_argument
:
Option
<
usize
>
)
{
if
let
Some
(
other
)
=
search_fun_environment_type
(
fun_decl
,
&
self
.clone
(),
until_fun_argument
)
{
let
other_type
=
other
.spl_type
.clone
();
if
self
.spl_type
!=
other_type
{
self
.spl_type
=
other
.spl_type
.clone
();
}
}
else
{
panic!
(
"referencing undeclared type variable `{}`"
,
self
)
}
}
}
// epic unification function
...
...
src/parser.rs
View file @
bfe531b5
...
...
@@ -293,15 +293,7 @@ impl Parser {
.map
(|
_
|
Box
::
new
(
infer
::
Type
::
Poly
(
polyvar_iter
.next
()
.unwrap
())))
.collect
();
let
return_type
=
Box
::
new
(
infer
::
Type
::
Poly
(
polyvar_iter
.next
()
.unwrap
()));
let
template
=
infer
::
FunctionSignature
{
args
:
arg_spl_types
,
ret
:
return_type
};
let
function_type
=
infer
::
FunctionType
{
template
:
template
,
signatures
:
Vec
::
new
(),
};
infer
::
Type
::
Function
(
function_type
)
infer
::
Type
::
Function
(
arg_spl_types
,
return_type
)
};
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment