Skip to content

Turn Datum into an enum - #105

Open
Twisol wants to merge 3 commits into
wduquette:masterfrom
Twisol:feature/datum-enum
Open

Turn Datum into an enum#105
Twisol wants to merge 3 commits into
wduquette:masterfrom
Twisol:feature/datum-enum

Conversation

@Twisol

@Twisol Twisol commented Aug 23, 2021

Copy link
Copy Markdown

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.
Comment thread molt/src/expr.rs
flt: 0.0,
str: String::new(),
}
Datum::String("".to_owned())

Copy link
Copy Markdown

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 thread molt/src/expr.rs
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
Copy Markdown

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 thread molt/src/expr.rs
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
Copy Markdown

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 thread molt/src/expr.rs
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)

@fogti fogti Sep 18, 2021

Copy link
Copy Markdown

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
Copy Markdown

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 thread molt/src/expr.rs
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
Copy Markdown

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 thread molt/src/expr.rs
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
Copy Markdown

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 thread molt/src/expr.rs
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
Copy Markdown

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