Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions crates/opy-rs/src/compiler/lowering/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,21 +218,11 @@ impl<'a> Lowering<'a> {
}
return Ok(self.push_value(Value::Null));
}
// The pinned OverPy oracle lowers a literal zero-index read
// (`arr[0]`, `arr[0.0]`) to `firstOf(arr)`; non-zero indexes
// and indexed writes keep the indexed forms.
let array = self.lower_value(array)?;
if matches!(index.as_ref(), Expr::Number { value, .. } if *value == 0.0) {
Value::Call {
name: "firstOf".to_string(),
args: vec![array],
}
} else {
let index = self.lower_value(index)?;
Value::Call {
name: "valueInArray".to_string(),
args: vec![array, index],
}
let index = self.lower_value(index)?;
Value::Call {
name: "valueInArray".to_string(),
args: vec![array, index],
}
}
Expr::Format { text, args, .. } => {
Expand Down
39 changes: 17 additions & 22 deletions crates/opy-rs/src/compiler/operator_optimization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,31 +836,26 @@ impl<'a> OperatorOptimizer<'a> {
}

fn value_in_array(&self, args: Vec<Value>) -> Rewrite {
let [array, index] = two(args);
let array = literal_array(array);
if let Value::Number(position) = index {
if position < 0.0 {
return Rewrite::Changed(Value::Null);
}
let position = position.round();
if let Value::Array(mut elements) = array {
if (position as usize) < elements.len() {
return Rewrite::Changed(elements.swap_remove(position as usize));
}
if !elements.is_empty() || !self.strict {
return Rewrite::Changed(Value::Null);
}
return Rewrite::Same(call(
"valueInArray",
vec![Value::Array(elements), Value::Number(position)],
));
let [mut array, index] = two(args);
array = literal_array(array);
let i = match (&array, index) {
(_, Value::Number(n)) if n < 0.0 => return Rewrite::Changed(Value::Null),
(Value::Array(items), Value::Number(n)) if self.strict && items.is_empty() => n,
(_, Value::Number(n)) => n.round(),
(_, index) => return Rewrite::Same(call("valueInArray", vec![array, index])),
};
if let Value::Array(items) = &mut array {
if (i as usize) < items.len() {
return Rewrite::Changed(items.swap_remove(i as usize));
}
if position == 0.0 {
return Rewrite::Changed(call("firstOf", vec![array]));
if !items.is_empty() || !self.strict {
return Rewrite::Changed(Value::Null);
}
return Rewrite::Same(call("valueInArray", vec![array, Value::Number(position)]));
}
Rewrite::Same(call("valueInArray", vec![array, index]))
if i == 0.0 {
return Rewrite::Changed(call("firstOf", vec![array]));
}
Rewrite::Same(call("valueInArray", vec![array, Value::Number(i)]))
}

fn component(args: Vec<Value>, axis: usize) -> Rewrite {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"schemaVersion": 1,
"id": "synthetic/structural-index-optimization",
"category": "compilation",
"features": [
"structural convergence",
"array indexing",
"disableOptimizations"
],
"source": "source.opy",
"tests": {
"source": {
"nativeStatus": "success",
"relationship": "match",
"ruleNames": true
},
"compiler": {
"nativeStatus": "success",
"relationship": "match",
"comparison": "semantic-wir",
"semanticEquivalent": true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"compile": {
"diagnostics": [],
"exitCode": 0,
"status": "success",
"stdout": "",
"workshop": "variables {\n global:\n 0: arr\n 1: result\n}\n\nrule (\"enabled zero indexing\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, First Of(Global.arr));\n Set Global Variable(result, First Of(Global.arr));\n Set Global Variable(result, Value In Array(Global.arr, 1));\n }\n}\n\n//Optimizations disabled\nrule (\"disabled zero indexing\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, Value In Array(Global.arr, 0));\n Set Global Variable(result, Value In Array(Global.arr, 0.0));\n Set Global Variable(result, Value In Array(Global.arr, 1));\n Set Global Variable(result, Value In Array(Empty Array, 0));\n Set Global Variable(result, Value In Array(Empty Array, 0.0));\n Set Global Variable(result, Value In Array(Empty Array, 1));\n }\n}\n\n//Optimizations enabled\nrule (\"reenabled zero indexing\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, First Of(Global.arr));\n }\n}\n\n//Strict optimizations enabled\nrule (\"strict empty array indexing\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, First Of(Empty Array));\n Set Global Variable(result, First Of(Empty Array));\n Set Global Variable(result, Value In Array(Empty Array, 1));\n Set Global Variable(result, Value In Array(Empty Array, 0.1));\n Set Global Variable(result, Value In Array(Empty Array, 0.49));\n }\n}\n",
"workshopExact": "variables {\n global:\n 0: arr\n 1: result\n}\n\nrule (\"enabled zero indexing\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, First Of(Global.arr));\n Set Global Variable(result, First Of(Global.arr));\n Set Global Variable(result, Value In Array(Global.arr, 1));\n }\n}\n\n//Optimizations disabled\nrule (\"disabled zero indexing\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, Value In Array(Global.arr, 0));\n Set Global Variable(result, Value In Array(Global.arr, 0.0));\n Set Global Variable(result, Value In Array(Global.arr, 1));\n Set Global Variable(result, Value In Array(Empty Array, 0));\n Set Global Variable(result, Value In Array(Empty Array, 0.0));\n Set Global Variable(result, Value In Array(Empty Array, 1));\n }\n}\n\n//Optimizations enabled\nrule (\"reenabled zero indexing\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, First Of(Global.arr));\n }\n}\n\n//Strict optimizations enabled\nrule (\"strict empty array indexing\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(result, First Of(Empty Array));\n Set Global Variable(result, First Of(Empty Array));\n Set Global Variable(result, Value In Array(Empty Array, 1));\n Set Global Variable(result, Value In Array(Empty Array, 0.1));\n Set Global Variable(result, Value In Array(Empty Array, 0.49));\n }\n}\n\n",
"workshopSha256": "4687610ab6d6c9e5c21d41595cf28d995c523e98c98ad1ed7834e8aa17bcea5d"
},
"fixture": "synthetic/structural-index-optimization",
"input": {
"files": [
{
"path": "source.opy",
"sha256": "314d849cbeb22cc56110be29a7881b36da2b36af0deaf6900a7ccc72b88b4ca4"
}
],
"sha256": "52c63f2dab1e4c45a9bc6551a37fb9c78649a074d1e1ad8579160658e466dfb8",
"source": "source.opy"
},
"oracle": {
"contentCommit": "5a7d0e294b8cad73b9701987bb584d0551d7fa4d",
"gitHead": "ec763c1d245aa5485ef61af5b2bda4975bce4877",
"integrity": "sha512-C5F6btT5yn19BvHuE0bjMuSd/2esebBabmpL4SYLQFuJ4IdouVOKEoMLLuJFAyNc0Phwrolblj5GDkDGYR0ofg==",
"language": "en-US",
"license": "GPL-3.0-only",
"name": "overpy",
"registryTarball": "https://registry.npmjs.org/overpy/-/overpy-9.7.17.tgz",
"repository": "https://github.com/Zezombye/overpy",
"version": "9.7.17"
},
"schemaVersion": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
globalvar arr
globalvar result

rule "enabled zero indexing":
@Event global
result = arr[0]
result = arr[0.0]
result = arr[1]

#!disableOptimizations

rule "disabled zero indexing":
@Event global
result = arr[0]
result = arr[0.0]
result = arr[1]
result = [][0]
result = [][0.0]
result = [][1]

#!enableOptimizations

rule "reenabled zero indexing":
@Event global
result = arr[0]

#!optimizeStrict

rule "strict empty array indexing":
@Event global
result = [][0]
result = [][0.0]
result = [][1]
result = [][0.1]
result = [][0.49]
Loading