Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turn Datum into an enum #105

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

Twisol
Copy link

@Twisol Twisol commented Aug 23, 2021

Hi Will -- it's Jonathan! This weekend, I'm making good on my years-old promise to check out Molt. Feel free to take or leave the changes in this PR; I had an idea to try out and it seems to have worked fairly nicely, but it's up to your discretion in the end.

This PR turns the existing struct Datum into a more Rust-y enum Datum, and propagates those changes throughout expr.rs. In the process, I ended up unifying the type coercion sections for each operator with their respective evaluation sections. I especially noticed an inconsistency between the assumptions made by execution for AND and OR and what the respective coercion was doing; I think the approach in this PR scopes the relevant assumptions much more tightly, so it'll be much more difficult for things to get out of sync like that.

This PR also contains minor contributions for the shift-right operator and absolute value function, which can both be simplified by using core Rust functionality. (Yes, as an arithmetic shift, >> is guaranteed to preserve sign!)

Lastly, I ran rustfmt on my changes to keep things consistent. I find some of the formatting choices it made to be less readable, but I defer to convention :)

Twisol added 3 commits August 22, 2021 19:53
Using an enum instead of a struct makes it impossible to use the wrong
field, and allows us to couple the tag-based dispatch with uses of
those fields.  This pays off significantly in type coercions for each
operator, where some new helper functions have been used to unify the
coercion and evaluation blocks.
flt: 0.0,
str: String::new(),
}
Datum::String("".to_owned())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Datum::String("".to_owned())
Datum::String(String::new())

Comment on lines 49 to 55
pub(crate) fn int(int: MoltInt) -> Self {
Self {
vtype: Type::Int,
int,
flt: 0.0,
str: String::new(),
}
Datum::Int(int)
}

pub(crate) fn float(flt: MoltFloat) -> Self {
Self {
vtype: Type::Float,
int: 0,
flt,
str: String::new(),
}
Datum::Float(flt)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods don't really contain any useful functionality anymore, it might be a good idea to replace any calls to them with direct invocations of the enum variant constructors

Comment on lines +240 to 244
match value {
Datum::Int(v) => molt_ok!(Value::from(v)),
Datum::Float(v) => molt_ok!(Value::from(v)),
Datum::String(v) => molt_ok!(Value::from(v)),
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this would work, but it might be worth trying

Suggested change
match value {
Datum::Int(v) => molt_ok!(Value::from(v)),
Datum::Float(v) => molt_ok!(Value::from(v)),
Datum::String(v) => molt_ok!(Value::from(v)),
}
molt_ok!(match value {
Datum::Int(v) => Value::from(v),
Datum::Float(v) => Value::from(v),
Datum::String(v) => Value::from(v),
})

Comment on lines -664 to +540
if value.int < 0 {
value.int = !((!value.int) >> value2.int)
} else {
value.int >>= value2.int;
}
value = Datum::Int(v1 >> v2)
Copy link

@fogti fogti Sep 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be a good idea to create a unit test which checks this assumption.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, if it is explicitly mentioned in the rust manual that won't be necessary.

Comment on lines +543 to 547
value = match coerce_pair(operator, &value, &value2)? {
DatumPair::Ints(v1, v2) => Datum::Int((v1 < v2) as MoltInt),
DatumPair::Floats(v1, v2) => Datum::Int((v1 < v2) as MoltInt),
DatumPair::Strings(v1, v2) => Datum::Int((v1 < v2) as MoltInt),
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
value = match coerce_pair(operator, &value, &value2)? {
DatumPair::Ints(v1, v2) => Datum::Int((v1 < v2) as MoltInt),
DatumPair::Floats(v1, v2) => Datum::Int((v1 < v2) as MoltInt),
DatumPair::Strings(v1, v2) => Datum::Int((v1 < v2) as MoltInt),
};
value = Datum::Int(match coerce_pair(operator, &value, &value2)? {
DatumPair::Ints(v1, v2) => v1 < v2,
DatumPair::Floats(v1, v2) => v1 < v2,
DatumPair::Strings(v1, v2) => v1 < v2,
} as MoltInt);

Comment on lines +550 to 554
value = match coerce_pair(operator, &value, &value2)? {
DatumPair::Ints(v1, v2) => Datum::Int((v1 > v2) as MoltInt),
DatumPair::Floats(v1, v2) => Datum::Int((v1 > v2) as MoltInt),
DatumPair::Strings(v1, v2) => Datum::Int((v1 > v2) as MoltInt),
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
value = match coerce_pair(operator, &value, &value2)? {
DatumPair::Ints(v1, v2) => Datum::Int((v1 > v2) as MoltInt),
DatumPair::Floats(v1, v2) => Datum::Int((v1 > v2) as MoltInt),
DatumPair::Strings(v1, v2) => Datum::Int((v1 > v2) as MoltInt),
};
value = Datum::Int(match coerce_pair(operator, &value, &value2)? {
DatumPair::Ints(v1, v2) => v1 > v2,
DatumPair::Floats(v1, v2) => v1 > v2,
DatumPair::Strings(v1, v2) => v1 > v2,
} as MoltInt);

Comment on lines +1281 to +1285
if v < 0.0 {
Ok(Datum::Int((v - 0.5) as MoltInt))
} else {
Ok(Datum::Int((v + 0.5) as MoltInt))
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if v < 0.0 {
Ok(Datum::Int((v - 0.5) as MoltInt))
} else {
Ok(Datum::Int((v + 0.5) as MoltInt))
}
Ok(Datum::Int(if v < 0.0 {
v - 0.5
} else {
v + 0.5
} as MoltInt))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants