diff --git a/editors/code/syntaxes/goboscript.tmGrammar.yml b/editors/code/syntaxes/goboscript.tmGrammar.yml
index 66d93a9d..7fa7df92 100644
--- a/editors/code/syntaxes/goboscript.tmGrammar.yml
+++ b/editors/code/syntaxes/goboscript.tmGrammar.yml
@@ -33,7 +33,7 @@ patterns:
- name: keyword.control
match: "\\b(if|else|elif|until|forever|repeat|delete|at|add|to|insert|true|false|as|struct|enum|return)\\b"
- name: keyword
- match: "\\b(error|warn|breakpoint|local|not|and|or|in|length|round|abs|floor|ceil|sqrt|sin|cos|tan|asin|acos|atan|ln|log|antiln|antilog)\\b"
+ match: "\\b(error|warn|breakpoint|local|not|and|or|of|in|length|round|abs|floor|ceil|sqrt|sin|cos|tan|asin|acos|atan|ln|log|antiln|antilog)\\b"
- name: support.function.builtin
match: "\\bset_layer_order\\b"
- name: support.function.builtin
diff --git a/editors/notepad++/goboscript.udl.xml b/editors/notepad++/goboscript.udl.xml
index 66b73c8e..19c36ad4 100644
--- a/editors/notepad++/goboscript.udl.xml
+++ b/editors/notepad++/goboscript.udl.xml
@@ -14,7 +14,7 @@
== ++ -- += -= *= /= //= %= &= != < > <= >= & + - * / // ; ( ) { } [ ] , |>
- not in length round abs floor ceil sqrt sin cos tan asin acos atan ln log antiln antilog %
+ not in length round abs floor ceil sqrt sin cos tan asin acos atan ln log antiln antilog % of
{
}
diff --git a/editors/sublime/goboscript.sublime-syntax b/editors/sublime/goboscript.sublime-syntax
index b464e047..b4af419e 100644
--- a/editors/sublime/goboscript.sublime-syntax
+++ b/editors/sublime/goboscript.sublime-syntax
@@ -25,7 +25,7 @@ contexts:
match: "\\b(if|else|elif|until|forever|repeat|delete|at|add|to|insert)\\b"
- scope: keyword
- match: "\\b(error|warn|breakpoint|local|not|and|or|in|length|round|abs|floor|ceil|sqrt|sin|cos|tan|asin|acos|atan|ln|log|antiln|antilog)\\b"
+ match: "\\b(error|warn|breakpoint|local|not|and|or|of|in|length|round|abs|floor|ceil|sqrt|sin|cos|tan|asin|acos|atan|ln|log|antiln|antilog)\\b"
- scope: support.function.builtin
match: "\\b(move|turn_left|turn_right|goto_random_position|goto_mouse_pointer|goto|glide|glide_to_random_position|glide_to_mouse_pointer|point_in_direction|point_towards_mouse_pointer|point_towards_random_direction|point_towards|change_x|set_x|change_y|set_y|if_on_edge_bounce|set_rotation_style_left_right|set_rotation_style_do_not_rotate|set_rotation_style_all_around|say|think|switch_costume|next_costume|switch_backdrop|next_backdrop|set_size|change_size|change_color_effect|change_fisheye_effect|change_whirl_effect|change_pixelate_effect|change_mosaic_effect|change_brightness_effect|change_ghost_effect|set_color_effect|set_fisheye_effect|set_whirl_effect|set_pixelate_effect|set_mosaic_effect|set_brightness_effect|set_ghost_effect|clear_graphic_effects|show|hide|goto_front|goto_back|go_forward|go_backward|play_sound_until_done|start_sound|stop_all_sounds|change_pitch_effect|change_pan_effect|set_pitch_effect|set_pan_effect|change_volume|set_volume|clear_sound_effects|broadcast|broadcast_and_wait|wait|wait_until|stop_all|stop_this_script|stop_other_scripts|delete_this_clone|clone|ask|set_drag_mode_draggable|set_drag_mode_not_draggable|reset_timer|erase_all|stamp|pen_down|pen_up|set_pen_color|change_pen_size|set_pen_size|rest|set_tempo|change_tempo)\\b"
diff --git a/src/ast/expr.rs b/src/ast/expr.rs
index 1945ff2c..221bfe73 100644
--- a/src/ast/expr.rs
+++ b/src/ast/expr.rs
@@ -53,6 +53,11 @@ pub enum Expr {
span: Span,
fields: Vec,
},
+ Of {
+ span: Span,
+ property: SmolStr,
+ object: SmolStr,
+ },
}
impl Expr {
@@ -67,6 +72,7 @@ impl Expr {
Self::UnOp { span, .. } => span.clone(),
Self::BinOp { span, .. } => span.clone(),
Self::StructLiteral { span, .. } => span.clone(),
+ Self::Of { span, .. } => span.clone(),
}
}
}
diff --git a/src/codegen/expr.rs b/src/codegen/expr.rs
index 1574552a..51a199b7 100644
--- a/src/codegen/expr.rs
+++ b/src/codegen/expr.rs
@@ -425,4 +425,32 @@ where T: Write + Seek
eprintln!("attempted to codegen Expr::Dot lhs = {lhs:#?}, rhs = {rhs:#?}");
Ok(())
}
+
+ pub fn property_of(
+ &mut self,
+ s: S,
+ d: D,
+ expr: &Expr,
+ this_id: NodeID,
+ parent_id: NodeID,
+ property: &SmolStr,
+ object: &SmolStr,
+ ) -> io::Result<()> {
+ let menu_id = self.id.new_id();
+ self.begin_node(
+ Node::new("sensing_of_object_menu", menu_id)
+ .parent_id(this_id)
+ .shadow(true)
+ )?;
+ self.single_field("OBJECT", object)?;
+ self.end_obj()?; // node
+
+ self.begin_node(Node::new("sensing_of", this_id).parent_id(parent_id))?;
+ self.begin_inputs()?;
+ self.input(s, d, "OBJECT", expr, menu_id)?;
+ self.end_obj()?; // inputs
+ self.single_field("PROPERTY", property)?;
+ self.end_obj()?; // node
+ Ok(())
+ }
}
diff --git a/src/codegen/input.rs b/src/codegen/input.rs
index 5bb7a120..67c881f3 100644
--- a/src/codegen/input.rs
+++ b/src/codegen/input.rs
@@ -148,7 +148,9 @@ where T: Write + Seek
node_id: NodeID,
shadow_id: Option,
) -> io::Result<()> {
- if ["CONDITION", "CONDITION2"].contains(&input_name) {
+ if ["OBJECT"].contains(&input_name) {
+ return write!(self, "[1,{node_id}]");
+ } else if ["CONDITION", "CONDITION2"].contains(&input_name) {
return write!(self, "[2,{node_id}]");
}
write!(self, "[3,{node_id},")?;
diff --git a/src/codegen/sb3.rs b/src/codegen/sb3.rs
index 0637c0b4..7deaadcd 100644
--- a/src/codegen/sb3.rs
+++ b/src/codegen/sb3.rs
@@ -1196,6 +1196,9 @@ where T: Write + Seek
Expr::Dot { lhs, rhs, rhs_span } => {
self.expr_dot(s, d, this_id, parent_id, lhs, rhs, rhs_span.clone())
}
+ Expr::Of { property, span, object} => {
+ self.property_of(s, d, expr, this_id, parent_id, property, object)
+ }
}
}
}
diff --git a/src/parser/grammar.lalrpop b/src/parser/grammar.lalrpop
index 43ec1303..74bc4e39 100644
--- a/src/parser/grammar.lalrpop
+++ b/src/parser/grammar.lalrpop
@@ -510,6 +510,7 @@ Term: Expr = {
}
},
"[" "]" => BinOp::Of.to_expr(l..r, term, index),
+ OF => Expr::Of { span: l..r, property, object },
"." => {
Expr::Dot { lhs: Box::new(lhs), rhs, rhs_span: l..r }
}
diff --git a/src/visitor/pass1.rs b/src/visitor/pass1.rs
index 90446558..42ea92fb 100644
--- a/src/visitor/pass1.rs
+++ b/src/visitor/pass1.rs
@@ -314,6 +314,9 @@ fn visit_expr(expr: &mut Expr, before: &mut Vec, s: &mut S) {
}
None
}
+ Expr::Of { span: _, property: _, object: _ } => {
+ None
+ },
};
if let Some(replace) = replace {
*expr = replace;
diff --git a/src/visitor/pass2.rs b/src/visitor/pass2.rs
index 2365fb6c..42af5d87 100644
--- a/src/visitor/pass2.rs
+++ b/src/visitor/pass2.rs
@@ -353,7 +353,8 @@ fn visit_expr(expr: &mut Expr, s: S, d: D, coerce_condition: bool) {
for field in fields {
visit_expr(&mut field.value, s, d, false);
}
- }
+ },
+ Expr::Of { span: _, property: _, object: _ } => {},
}
transformations::apply(expr, transformations::minus);
transformations::apply(expr, transformations::less_than_equal);
diff --git a/tests/sensing/main.gs b/tests/sensing/main.gs
index e0e00253..703be685 100644
--- a/tests/sensing/main.gs
+++ b/tests/sensing/main.gs
@@ -28,4 +28,5 @@ onflag {
say current_second();
say days_since_2000();
say username();
+ say direction of foo;
}