diff --git a/crates/opy-provider/src/edits.rs b/crates/opy-provider/src/edits.rs index 34b37013..cc5ddcbd 100644 --- a/crates/opy-provider/src/edits.rs +++ b/crates/opy-provider/src/edits.rs @@ -14,203 +14,10 @@ use crate::{ path_to_file_uri, resolved_path, same_path, validate_documents, }; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum DiagnosticClass { - DocumentSyntax, - MissingSource, - NameBinding, - MergedTable, - MacroTable, - Script, - ExternalFile, - Catalog, - Capability, - Semantic, - Internal, - WarningOnly, -} - -const CODE_CLASSES: &[(DiagnosticClass, &[&str])] = &[ - ( - DiagnosticClass::DocumentSyntax, - &[ - "lex-error", - "parse-error", - "workshop-source", - "directive-invalid", - "unsupported-directive", - "include-invalid", - "define-invalid", - "main-file-invalid", - "main-file-placement", - "rule-prefix-invalid", - "settings-invalid", - "settings-placement", - "macro-invalid", - "do-while-placement", - "invalid-string-entity", - "unknown-string-entity", - "script-invalid", - "enum-increment", - ], - ), - ( - DiagnosticClass::MissingSource, - &[ - "include-not-found", - "main-file-not-found", - "script-not-found", - "unknown-identifier", - "unknown-action", - "unknown-value", - "unknown-member", - ], - ), - ( - DiagnosticClass::NameBinding, - &[ - "duplicate-argument", - "duplicate-declaration", - "duplicate-definition", - "duplicate-rule-name", - "enum-type-without-member", - "invalid-arity", - "vect-arity", - "unresolved-reference", - "unknown-keyword", - ], - ), - ( - DiagnosticClass::MergedTable, - &[ - "rule-prefix-template-duplicate", - "replacement-duplicate", - "post-compile-hook-duplicate", - "macro-redeclaration", - ], - ), - ( - DiagnosticClass::MacroTable, - &["macro-arity", "macro-recursion"], - ), - ( - DiagnosticClass::Script, - &[ - "script-error", - "script-timeout", - "script-stack-limit", - "script-memory-limit", - "script-result-not-string", - "script-internal", - ], - ), - ( - DiagnosticClass::ExternalFile, - &[ - "include-cycle", - "settings-not-found", - "translations-invalid", - "settings-expression", - "rule-prefix-template-invalid", - ], - ), - ( - DiagnosticClass::Catalog, - &[ - "catalog-error", - "manifest-error", - "unknown-enum-member", - "missing-mapping", - "unknown-texture-member", - ], - ), - ( - DiagnosticClass::Capability, - &[ - "backend-directive-unsupported", - "four-dimensional-assignment", - "four-dimensional-delete", - "index-collision", - "index-exhausted", - "index-out-of-range", - "random-indexed-delete", - "split-dict-array-arguments", - "split-dict-array-arity", - "split-dict-array-key", - "symbol-collision", - "workshop-action-layout", - "unsupported-action-call", - "unsupported-construct", - "unsupported-control-flow", - "unsupported-dangling", - "unsupported-duplicate-name", - "unsupported-enum-domain", - "unsupported-enum-domain-mismatch", - "unsupported-enum-member", - "unsupported-index", - "unsupported-indexed-initializer", - "unsupported-integration-surface", - "unsupported-invalid-argument", - "unsupported-invalid-arity", - "unsupported-localized-string", - "unsupported-member", - "unsupported-member-assignment", - "unsupported-missing-argument", - "unsupported-modify-op", - "unsupported-non-finite-number", - "unsupported-rule-order", - "unsupported-settings", - "unsupported-subroutine-value", - "unsupported-value-call", - ], - ), - ( - DiagnosticClass::Semantic, - &[ - "action-in-value-position", - "break-context", - "continue-context", - "dict-access", - "invalid-argument", - "invalid-call-context", - "invalid-identifier", - "invalid-iterable", - "invalid-range-binder", - "invalid-receiver", - "invalid-span", - "invalid-string-modifier", - "invalid-structure", - "keyword-required", - "keyword-unsupported", - "lambda-context", - "missing-argument", - "positional-after-keyword", - "settings-hero-lists", - "settings-workshop-value", - "tabular-arguments", - "value-in-action-position", - ], - ), - ( - DiagnosticClass::Internal, - &[ - "incompatible-protocol", - "malformed-payload", - "unsupported-node", - "workshop-emission", - ], - ), - (DiagnosticClass::WarningOnly, &["unknown-setting"]), -]; - -fn class_of(code: &str) -> Option { - CODE_CLASSES - .iter() - .find_map(|(class, codes)| codes.contains(&code).then_some(*class)) -} - +mod diagnostics; #[cfg(test)] -const NON_DIAGNOSTIC_LITERALS: &[&str] = &["kebab-case", "non-empty"]; +use diagnostics::{CODE_CLASSES, NON_DIAGNOSTIC_LITERALS}; +use diagnostics::{DiagnosticClass, class_of}; #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/crates/opy-provider/src/edits/diagnostics.rs b/crates/opy-provider/src/edits/diagnostics.rs new file mode 100644 index 00000000..6add13af --- /dev/null +++ b/crates/opy-provider/src/edits/diagnostics.rs @@ -0,0 +1,198 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(super) enum DiagnosticClass { + DocumentSyntax, + MissingSource, + NameBinding, + MergedTable, + MacroTable, + Script, + ExternalFile, + Catalog, + Capability, + Semantic, + Internal, + WarningOnly, +} + +pub(super) const CODE_CLASSES: &[(DiagnosticClass, &[&str])] = &[ + ( + DiagnosticClass::DocumentSyntax, + &[ + "lex-error", + "parse-error", + "workshop-source", + "directive-invalid", + "unsupported-directive", + "include-invalid", + "define-invalid", + "main-file-invalid", + "main-file-placement", + "rule-prefix-invalid", + "settings-invalid", + "settings-placement", + "macro-invalid", + "do-while-placement", + "invalid-string-entity", + "unknown-string-entity", + "script-invalid", + "enum-increment", + ], + ), + ( + DiagnosticClass::MissingSource, + &[ + "include-not-found", + "main-file-not-found", + "script-not-found", + "unknown-identifier", + "unknown-action", + "unknown-value", + "unknown-member", + ], + ), + ( + DiagnosticClass::NameBinding, + &[ + "duplicate-argument", + "duplicate-declaration", + "duplicate-definition", + "duplicate-rule-name", + "enum-type-without-member", + "invalid-arity", + "vect-arity", + "unresolved-reference", + "unknown-keyword", + ], + ), + ( + DiagnosticClass::MergedTable, + &[ + "rule-prefix-template-duplicate", + "replacement-duplicate", + "post-compile-hook-duplicate", + "macro-redeclaration", + ], + ), + ( + DiagnosticClass::MacroTable, + &["macro-arity", "macro-recursion"], + ), + ( + DiagnosticClass::Script, + &[ + "script-error", + "script-timeout", + "script-stack-limit", + "script-memory-limit", + "script-result-not-string", + "script-internal", + ], + ), + ( + DiagnosticClass::ExternalFile, + &[ + "include-cycle", + "settings-not-found", + "translations-invalid", + "settings-expression", + "rule-prefix-template-invalid", + ], + ), + ( + DiagnosticClass::Catalog, + &[ + "catalog-error", + "manifest-error", + "unknown-enum-member", + "missing-mapping", + "unknown-texture-member", + ], + ), + ( + DiagnosticClass::Capability, + &[ + "backend-directive-unsupported", + "four-dimensional-assignment", + "four-dimensional-delete", + "index-collision", + "index-exhausted", + "index-out-of-range", + "random-indexed-delete", + "split-dict-array-arguments", + "split-dict-array-arity", + "split-dict-array-key", + "symbol-collision", + "workshop-action-layout", + "unsupported-action-call", + "unsupported-construct", + "unsupported-control-flow", + "unsupported-dangling", + "unsupported-duplicate-name", + "unsupported-enum-domain", + "unsupported-enum-domain-mismatch", + "unsupported-enum-member", + "unsupported-index", + "unsupported-indexed-initializer", + "unsupported-integration-surface", + "unsupported-invalid-argument", + "unsupported-invalid-arity", + "unsupported-localized-string", + "unsupported-member", + "unsupported-member-assignment", + "unsupported-missing-argument", + "unsupported-modify-op", + "unsupported-non-finite-number", + "unsupported-rule-order", + "unsupported-settings", + "unsupported-subroutine-value", + "unsupported-value-call", + ], + ), + ( + DiagnosticClass::Semantic, + &[ + "action-in-value-position", + "break-context", + "continue-context", + "dict-access", + "invalid-argument", + "invalid-call-context", + "invalid-identifier", + "invalid-iterable", + "invalid-range-binder", + "invalid-receiver", + "invalid-span", + "invalid-string-modifier", + "invalid-structure", + "keyword-required", + "keyword-unsupported", + "lambda-context", + "missing-argument", + "positional-after-keyword", + "rule-event-gate", + "settings-hero-lists", + "settings-workshop-value", + "tabular-arguments", + "value-in-action-position", + ], + ), + ( + DiagnosticClass::Internal, + &[ + "incompatible-protocol", + "malformed-payload", + "unsupported-node", + "workshop-emission", + ], + ), + (DiagnosticClass::WarningOnly, &["unknown-setting"]), +]; + +pub(super) fn class_of(code: &str) -> Option { + CODE_CLASSES + .iter() + .find_map(|(class, codes)| codes.contains(&code).then_some(*class)) +} + +#[cfg(test)] +pub(super) const NON_DIAGNOSTIC_LITERALS: &[&str] = &["kebab-case", "non-empty"]; diff --git a/crates/opy-rs/src/compiler/tests/variable_initializers.rs b/crates/opy-rs/src/compiler/tests/variable_initializers.rs index 9336d733..d037cb8c 100644 --- a/crates/opy-rs/src/compiler/tests/variable_initializers.rs +++ b/crates/opy-rs/src/compiler/tests/variable_initializers.rs @@ -2,6 +2,34 @@ use std::path::Path; use crate::Compiler; +#[test] +fn global_initializers_reject_event_player_inside_expressions() { + for value in [ + "eventPlayer", + "eventPlayer()", + "[eventPlayer]", + "eventPlayer.getPosition()", + ] { + let source = format!("globalvar target = {value}\n"); + let error = crate::compile(&source, "initializer.opy", Path::new(".")).unwrap_err(); + assert_eq!(error.code, "rule-event-gate", "{value}"); + assert_eq!(error.span.unwrap().start.line, 1, "{value}"); + } +} + +#[test] +fn player_initializers_keep_event_player_context() { + let source = "playervar target = eventPlayer\n"; + let hir = crate::compile(source, "initializer.opy", Path::new(".")).unwrap(); + let artifact = Compiler::new().unwrap().compile_hir(&hir).unwrap(); + assert!(matches!( + artifact.wir.rules[0].actions.first(), + Some(workshop_rs::Action::SetPlayerVariable { player, value, .. }) + if matches!(player, workshop_rs::Value::EventPlayer) + && matches!(value, workshop_rs::Value::EventPlayer) + )); +} + #[test] fn explicit_null_initializers_are_emitted_for_global_and_player_variables() { let source = r#" diff --git a/crates/opy-rs/src/lower.rs b/crates/opy-rs/src/lower.rs index 11826102..22be807a 100644 --- a/crates/opy-rs/src/lower.rs +++ b/crates/opy-rs/src/lower.rs @@ -163,9 +163,7 @@ fn lower_program( lowerer.current_order = order; match item { TopLevel::Declaration(decl) => { - if let Some(declaration) = lowerer.lower_declaration(decl) { - declarations.push(declaration); - } + declarations.extend(lowerer.lower_declaration(decl, &declarations)); } TopLevel::Rule(CstRuleEntry::Rule(rule)) => rules.push(RuleEntry::Rule( lowerer.lower_rule(rule, files.as_slice(), preprocessing)?, diff --git a/crates/opy-rs/src/lower/declarations.rs b/crates/opy-rs/src/lower/declarations.rs index 3cfa5ee9..ad53ada4 100644 --- a/crates/opy-rs/src/lower/declarations.rs +++ b/crates/opy-rs/src/lower/declarations.rs @@ -11,7 +11,11 @@ fn declaration_visible( } impl Lowerer { - pub(super) fn lower_declaration(&mut self, decl: &Decl) -> Option { + pub(super) fn lower_declaration( + &mut self, + decl: &Decl, + declarations: &[Declaration], + ) -> Option { match decl { Decl::GlobalVariable { name, @@ -24,7 +28,7 @@ impl Lowerer { index: *index, span: Some(span.into()), name_span: Some(name_span.into()), - initializer: self.initializer(initializer.as_ref()), + initializer: self.global_initializer(initializer.as_ref(), declarations), }), Decl::PlayerVariable { name, @@ -191,6 +195,82 @@ impl Lowerer { declaration_visible(&self.enum_declarations, name, self.current_order) } + fn global_initializer( + &mut self, + initializer: Option<&Expr>, + declarations: &[Declaration], + ) -> Option> { + use crate::hir::visit::{self, Visitor}; + + struct EventPlayerCheck<'a> { + declarations: &'a [Declaration], + visited: HashSet<(std::mem::Discriminant, &'a str)>, + found: bool, + } + + impl Visitor for EventPlayerCheck<'_> { + fn visit_expr(&mut self, expression: &HirExpr) { + match expression { + HirExpr::EventPlayer { .. } => self.found = true, + HirExpr::Constant { name, .. } | HirExpr::MacroCall { name, .. } => { + for declaration in self.declarations { + match (expression, declaration) { + ( + HirExpr::Constant { .. }, + Declaration::Constant { + name: defined, + value, + .. + }, + ) if defined == name + && self + .visited + .insert((std::mem::discriminant(declaration), defined)) => + { + self.visit_expr(value); + } + ( + HirExpr::MacroCall { .. }, + Declaration::Macro { + name: defined, + body, + .. + }, + ) if defined == name + && self + .visited + .insert((std::mem::discriminant(declaration), defined)) => + { + visit::walk_stmts(self, body); + } + _ => {} + } + } + } + _ => {} + } + visit::walk_expr(self, expression); + } + } + + let initializer = initializer?; + let value = self.initializer(Some(initializer))?; + let mut check = EventPlayerCheck { + declarations, + visited: HashSet::new(), + found: false, + }; + check.visit_expr(&value); + if check.found { + self.error_at( + "rule-event-gate", + "Cannot use 'eventPlayer' with rule event 'global'".to_string(), + initializer.span(), + ); + } + Some(value) + } + /// A declaration initializer: integer-`0` literal initializers are /// dropped (matching the reference adapter, which drops `h = 0` but /// carries `j = 5` and `k = 0.0`); other initializers are kept. diff --git a/crates/opy-rs/src/parser/expressions.rs b/crates/opy-rs/src/parser/expressions.rs index f2020f4b..7fac6d48 100644 --- a/crates/opy-rs/src/parser/expressions.rs +++ b/crates/opy-rs/src/parser/expressions.rs @@ -1,5 +1,7 @@ use super::*; +mod arithmetic; + impl Parser<'_> { pub(super) fn parse_expr(&mut self) -> Result { self.parse_expr_inner(false) @@ -111,84 +113,6 @@ impl Parser<'_> { Ok(left) } - fn parse_additive(&mut self) -> Result { - self.skip_expression_newlines(); - let mut left = self.parse_multiplicative()?; - loop { - self.skip_expression_newlines(); - if self.peek_kind() == TokenKind::Decrement - && !matches!(self.peek_at(1).kind, TokenKind::Newline | TokenKind::Eof) - { - let operator = self.advance(); - let operand = self.parse_unary()?; - let unary = unary_op("-", operator.span, operand); - let right = self.parse_multiplicative_tail(unary)?; - left = binary("-", left, right); - continue; - } - let op = match self.peek_kind() { - TokenKind::Plus => "+", - TokenKind::Minus => "-", - _ => break, - }; - self.bump(); - self.skip_expression_newlines(); - let right = self.parse_multiplicative()?; - left = binary(op, left, right); - } - Ok(left) - } - - fn parse_multiplicative(&mut self) -> Result { - self.skip_expression_newlines(); - let left = self.parse_unary()?; - self.parse_multiplicative_tail(left) - } - - fn parse_multiplicative_tail(&mut self, mut left: Expr) -> Result { - loop { - self.skip_expression_newlines(); - let op = match self.peek_kind() { - TokenKind::Star => "*", - TokenKind::Slash => "/", - TokenKind::Percent => "%", - _ => break, - }; - self.bump(); - self.skip_expression_newlines(); - let right = self.parse_unary()?; - left = binary(op, left, right); - } - Ok(left) - } - - fn parse_unary(&mut self) -> Result { - self.skip_expression_newlines(); - if matches!(self.peek_kind(), TokenKind::Minus | TokenKind::Decrement) { - let start = self.advance(); - self.skip_expression_newlines(); - let operand = self.parse_unary()?; - let unary = unary_op("-", start.span, operand); - if start.kind == TokenKind::Decrement { - return Ok(unary_op("-", start.span, unary)); - } - return Ok(unary); - } - self.parse_power() - } - - fn parse_power(&mut self) -> Result { - let base = self.parse_postfix()?; - self.skip_expression_newlines(); - if self.peek_kind() == TokenKind::DoubleStar { - self.bump(); - self.skip_expression_newlines(); - let exponent = self.parse_unary()?; - return Ok(binary("**", base, exponent)); - } - Ok(base) - } - pub(super) fn parse_postfix(&mut self) -> Result { let mut base = self.parse_primary()?; loop { diff --git a/crates/opy-rs/src/parser/expressions/arithmetic.rs b/crates/opy-rs/src/parser/expressions/arithmetic.rs new file mode 100644 index 00000000..265dc47f --- /dev/null +++ b/crates/opy-rs/src/parser/expressions/arithmetic.rs @@ -0,0 +1,91 @@ +use super::*; + +impl Parser<'_> { + pub(super) fn parse_additive(&mut self) -> Result { + self.skip_expression_newlines(); + let mut left = self.parse_multiplicative()?; + loop { + self.skip_expression_newlines(); + if matches!( + self.peek_kind(), + TokenKind::Increment | TokenKind::Decrement + ) && !matches!(self.peek_at(1).kind, TokenKind::Newline | TokenKind::Eof) + { + let operator = self.advance(); + let operand = self.parse_unary()?; + let (op, right) = if operator.kind == TokenKind::Decrement { + ("-", unary_op("-", operator.span, operand)) + } else { + ("+", operand) + }; + let right = self.parse_multiplicative_tail(right)?; + left = binary(op, left, right); + continue; + } + let op = match self.peek_kind() { + TokenKind::Plus => "+", + TokenKind::Minus => "-", + _ => break, + }; + self.bump(); + self.skip_expression_newlines(); + let right = self.parse_multiplicative()?; + left = binary(op, left, right); + } + Ok(left) + } + + fn parse_multiplicative(&mut self) -> Result { + self.skip_expression_newlines(); + let left = self.parse_unary()?; + self.parse_multiplicative_tail(left) + } + + fn parse_multiplicative_tail(&mut self, mut left: Expr) -> Result { + loop { + self.skip_expression_newlines(); + let op = match self.peek_kind() { + TokenKind::Star => "*", + TokenKind::Slash => "/", + TokenKind::Percent => "%", + _ => break, + }; + self.bump(); + self.skip_expression_newlines(); + let right = self.parse_unary()?; + left = binary(op, left, right); + } + Ok(left) + } + + fn parse_unary(&mut self) -> Result { + self.skip_expression_newlines(); + if matches!(self.peek_kind(), TokenKind::Plus | TokenKind::Increment) { + self.bump(); + return self.parse_unary(); + } + if matches!(self.peek_kind(), TokenKind::Minus | TokenKind::Decrement) { + let start = self.advance(); + self.skip_expression_newlines(); + let operand = self.parse_unary()?; + let unary = unary_op("-", start.span, operand); + if start.kind == TokenKind::Decrement { + return Ok(unary_op("-", start.span, unary)); + } + return Ok(unary); + } + self.parse_power() + } + + fn parse_power(&mut self) -> Result { + let base = self.parse_postfix()?; + self.skip_expression_newlines(); + if self.peek_kind() == TokenKind::DoubleStar { + self.bump(); + self.skip_expression_newlines(); + let exponent = self.parse_unary()?; + return Ok(binary("**", base, exponent)); + } + Ok(base) + } +} diff --git a/crates/opy-rs/src/parser/statements.rs b/crates/opy-rs/src/parser/statements.rs index e1d0c4ab..782e0825 100644 --- a/crates/opy-rs/src/parser/statements.rs +++ b/crates/opy-rs/src/parser/statements.rs @@ -142,6 +142,13 @@ impl Parser<'_> { } pub(super) fn parse_expr_statement(&mut self) -> Result { + let starts_with_increment = self.peek_kind() == TokenKind::Increment; + if starts_with_increment + && matches!(self.peek_at(1).kind, TokenKind::Newline | TokenKind::Eof) + { + self.error_at_current("prefix increment is not a standalone assignment".to_string()); + return Err(()); + } if self.peek_kind() == TokenKind::LParen { let save_pos = self.pos; let save_errors = self.errors.len(); @@ -231,6 +238,14 @@ impl Parser<'_> { span, }) } + _ if starts_with_increment => { + self.errors.push(OpyError::at( + "parse-error", + "prefix increment is not a standalone assignment".to_string(), + start, + )); + Err(()) + } _ => { let end = expr.span().end; Ok(Stmt::Expr { diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-invalid/fixture.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-invalid/fixture.json new file mode 100644 index 00000000..e2557308 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-invalid/fixture.json @@ -0,0 +1,26 @@ +{ + "schemaVersion": 1, + "id": "synthetic/constant-first-macro-initializer-invalid", + "category": "diagnostics", + "features": [ + "declaration initializers", + "event context", + "constant and callable macro namespaces" + ], + "source": "source.opy", + "tests": { + "source": { + "nativeStatus": "failure", + "relationship": "match", + "ruleNames": false, + "diagnosticCode": "rule-event-gate" + }, + "compiler": { + "nativeStatus": "failure", + "relationship": "match", + "comparison": "diagnostic-code", + "diagnosticCode": "rule-event-gate", + "failureClass": "frontend" + } + } +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-invalid/oracle.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-invalid/oracle.json new file mode 100644 index 00000000..9393784d --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-invalid/oracle.json @@ -0,0 +1,39 @@ +{ + "compile": { + "diagnostics": [ + { + "severity": "error", + "text": "Error: Cannot use 'eventPlayer' with rule event 'global'\n | line 3, col 5, at source.opy\n | line 4, col 24, at source.opy" + } + ], + "exitCode": 1, + "status": "failure", + "stdout": "", + "workshop": "", + "workshopExact": "", + "workshopSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "fixture": "synthetic/constant-first-macro-initializer-invalid", + "input": { + "files": [ + { + "path": "source.opy", + "sha256": "4ae5da3417f76af7324148f1a2aeb2f9d7c3f26e044e61fb0efbcb870677c0a6" + } + ], + "sha256": "25bc658cf790b00b9daf2ab21ba6fd08e484bcfe5907a2e558f784c194f54185", + "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 +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-invalid/source.opy b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-invalid/source.opy new file mode 100644 index 00000000..81c0fd0c --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-invalid/source.opy @@ -0,0 +1,4 @@ +macro p = 1 +macro p(): + eventPlayer +globalvar target = [p, p()] diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-safe/fixture.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-safe/fixture.json new file mode 100644 index 00000000..59b33cf1 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-safe/fixture.json @@ -0,0 +1,24 @@ +{ + "schemaVersion": 1, + "id": "synthetic/constant-first-macro-initializer-safe", + "category": "compilation", + "features": [ + "declaration initializers", + "event context", + "constant and callable macro namespaces" + ], + "source": "source.opy", + "tests": { + "source": { + "nativeStatus": "success", + "relationship": "match", + "ruleNames": true + }, + "compiler": { + "nativeStatus": "success", + "relationship": "match", + "comparison": "semantic-wir", + "semanticEquivalent": true + } + } +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-safe/oracle.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-safe/oracle.json new file mode 100644 index 00000000..1ba84587 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-safe/oracle.json @@ -0,0 +1,34 @@ +{ + "compile": { + "diagnostics": [], + "exitCode": 0, + "status": "success", + "stdout": "", + "workshop": "variables {\n global:\n 0: target\n player:\n 0: playerTarget\n}\n\nrule (\"Initialize global variables\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(target, 1);\n }\n}\n\nrule (\"Initialize player variables\") {\n event {\n Ongoing - Each Player;\n All;\n All;\n }\n actions {\n Set Player Variable(Event Player, playerTarget, Event Player);\n }\n}\n", + "workshopExact": "variables {\n global:\n 0: target\n player:\n 0: playerTarget\n}\n\nrule (\"Initialize global variables\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(target, 1);\n }\n}\n\nrule (\"Initialize player variables\") {\n event {\n Ongoing - Each Player;\n All;\n All;\n }\n actions {\n Set Player Variable(Event Player, playerTarget, Event Player);\n }\n}\n\n", + "workshopSha256": "31f5cdf794b0aac9089c83027ff555e374d2c6e6d0fa85140b98f3f3c51d2b77" + }, + "fixture": "synthetic/constant-first-macro-initializer-safe", + "input": { + "files": [ + { + "path": "source.opy", + "sha256": "d15687f4dfd578243bae80736a29b757ed7b8ff1f3e000790cfa785df0c89492" + } + ], + "sha256": "edb71f43ec5026813a6df26c82a301ce8073082163b4532fce50e1d53ac5dc84", + "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 +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-safe/source.opy b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-safe/source.opy new file mode 100644 index 00000000..f7ad82cb --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/constant-first-macro-initializer-safe/source.opy @@ -0,0 +1,5 @@ +macro p = eventPlayer +macro p(): + 1 +globalvar target = p() +playervar playerTarget = p diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-constant-event-player-invalid/fixture.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-constant-event-player-invalid/fixture.json new file mode 100644 index 00000000..ea402bed --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-constant-event-player-invalid/fixture.json @@ -0,0 +1,25 @@ +{ + "schemaVersion": 1, + "id": "synthetic/global-initializer-constant-event-player-invalid", + "category": "diagnostics", + "features": [ + "declaration initializers", + "event context" + ], + "source": "source.opy", + "tests": { + "source": { + "nativeStatus": "failure", + "relationship": "match", + "ruleNames": false, + "diagnosticCode": "rule-event-gate" + }, + "compiler": { + "nativeStatus": "failure", + "relationship": "match", + "comparison": "diagnostic-code", + "diagnosticCode": "rule-event-gate", + "failureClass": "frontend" + } + } +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-constant-event-player-invalid/oracle.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-constant-event-player-invalid/oracle.json new file mode 100644 index 00000000..2b633733 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-constant-event-player-invalid/oracle.json @@ -0,0 +1,39 @@ +{ + "compile": { + "diagnostics": [ + { + "severity": "error", + "text": "Error: Cannot use 'eventPlayer' with rule event 'global'\n | line 2, col 16, at source.opy" + } + ], + "exitCode": 1, + "status": "failure", + "stdout": "", + "workshop": "", + "workshopExact": "", + "workshopSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "fixture": "synthetic/global-initializer-constant-event-player-invalid", + "input": { + "files": [ + { + "path": "source.opy", + "sha256": "d32e111879579934051eb2cfdfed86f62b724309b074b9f23b7ada9a73669e23" + } + ], + "sha256": "3a70c640a8c2ec75136fa8a045da3ac5ba37547e716bd7bb94bea277c197c765", + "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 +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-constant-event-player-invalid/source.opy b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-constant-event-player-invalid/source.opy new file mode 100644 index 00000000..54865e34 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-constant-event-player-invalid/source.opy @@ -0,0 +1,3 @@ +macro p = eventPlayer +macro chain = [p] +globalvar target = chain diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-event-player-invalid/fixture.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-event-player-invalid/fixture.json new file mode 100644 index 00000000..89abe831 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-event-player-invalid/fixture.json @@ -0,0 +1,25 @@ +{ + "schemaVersion": 1, + "id": "synthetic/global-initializer-event-player-invalid", + "category": "diagnostics", + "features": [ + "declaration initializers", + "event context" + ], + "source": "source.opy", + "tests": { + "source": { + "nativeStatus": "failure", + "relationship": "match", + "ruleNames": false, + "diagnosticCode": "rule-event-gate" + }, + "compiler": { + "nativeStatus": "failure", + "relationship": "match", + "comparison": "diagnostic-code", + "diagnosticCode": "rule-event-gate", + "failureClass": "frontend" + } + } +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-event-player-invalid/oracle.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-event-player-invalid/oracle.json new file mode 100644 index 00000000..d01d2718 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-event-player-invalid/oracle.json @@ -0,0 +1,39 @@ +{ + "compile": { + "diagnostics": [ + { + "severity": "error", + "text": "Error: Cannot use 'eventPlayer' with rule event 'global'\n | line 1, col 20, at source.opy" + } + ], + "exitCode": 1, + "status": "failure", + "stdout": "", + "workshop": "", + "workshopExact": "", + "workshopSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "fixture": "synthetic/global-initializer-event-player-invalid", + "input": { + "files": [ + { + "path": "source.opy", + "sha256": "6279468fe6ed59b12ac9c179a47e9572b70c4af52d7147c0c65eb13cb47f2f7b" + } + ], + "sha256": "24a17151c72b71c36a6eb3c24702f7d2f84023988fe96e6204914301b13ac471", + "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 +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-event-player-invalid/source.opy b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-event-player-invalid/source.opy new file mode 100644 index 00000000..e17f2e00 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-event-player-invalid/source.opy @@ -0,0 +1 @@ +globalvar target = eventPlayer diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-macro-event-player-invalid/fixture.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-macro-event-player-invalid/fixture.json new file mode 100644 index 00000000..3ecab7c4 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-macro-event-player-invalid/fixture.json @@ -0,0 +1,25 @@ +{ + "schemaVersion": 1, + "id": "synthetic/global-initializer-macro-event-player-invalid", + "category": "diagnostics", + "features": [ + "declaration initializers", + "event context" + ], + "source": "source.opy", + "tests": { + "source": { + "nativeStatus": "failure", + "relationship": "match", + "ruleNames": false, + "diagnosticCode": "rule-event-gate" + }, + "compiler": { + "nativeStatus": "failure", + "relationship": "match", + "comparison": "diagnostic-code", + "diagnosticCode": "rule-event-gate", + "failureClass": "frontend" + } + } +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-macro-event-player-invalid/oracle.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-macro-event-player-invalid/oracle.json new file mode 100644 index 00000000..258ae902 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-macro-event-player-invalid/oracle.json @@ -0,0 +1,39 @@ +{ + "compile": { + "diagnostics": [ + { + "severity": "error", + "text": "Error: Cannot use 'eventPlayer' with rule event 'global'\n | line 2, col 5, at source.opy\n | line 4, col 5, at source.opy\n | line 5, col 20, at source.opy" + } + ], + "exitCode": 1, + "status": "failure", + "stdout": "", + "workshop": "", + "workshopExact": "", + "workshopSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "fixture": "synthetic/global-initializer-macro-event-player-invalid", + "input": { + "files": [ + { + "path": "source.opy", + "sha256": "afd95840b6cb63f590b64d04fcb18a0158e696a4e4faf531386fb7fb6d0482ca" + } + ], + "sha256": "6b75483b6cab3bc469acf84ca49b9086d15dd511a172dfcf741aea72e7c18b3d", + "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 +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-macro-event-player-invalid/source.opy b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-macro-event-player-invalid/source.opy new file mode 100644 index 00000000..f4a790be --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/global-initializer-macro-event-player-invalid/source.opy @@ -0,0 +1,5 @@ +macro p(): + eventPlayer +macro nested(): + p() +globalvar target = nested() diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-invalid/fixture.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-invalid/fixture.json new file mode 100644 index 00000000..4f5f1b26 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-invalid/fixture.json @@ -0,0 +1,26 @@ +{ + "schemaVersion": 1, + "id": "synthetic/macro-first-constant-initializer-invalid", + "category": "diagnostics", + "features": [ + "declaration initializers", + "event context", + "constant and callable macro namespaces" + ], + "source": "source.opy", + "tests": { + "source": { + "nativeStatus": "failure", + "relationship": "match", + "ruleNames": false, + "diagnosticCode": "rule-event-gate" + }, + "compiler": { + "nativeStatus": "failure", + "relationship": "match", + "comparison": "diagnostic-code", + "diagnosticCode": "rule-event-gate", + "failureClass": "frontend" + } + } +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-invalid/oracle.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-invalid/oracle.json new file mode 100644 index 00000000..f774c1b5 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-invalid/oracle.json @@ -0,0 +1,39 @@ +{ + "compile": { + "diagnostics": [ + { + "severity": "error", + "text": "Error: Cannot use 'eventPlayer' with rule event 'global'\n | line 4, col 26, at source.opy" + } + ], + "exitCode": 1, + "status": "failure", + "stdout": "", + "workshop": "", + "workshopExact": "", + "workshopSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "fixture": "synthetic/macro-first-constant-initializer-invalid", + "input": { + "files": [ + { + "path": "source.opy", + "sha256": "1df59f21d4de16327de98b4968242200064900f135adc6b08a7ad9c1f19305bb" + } + ], + "sha256": "aa18365b4b262a0123e24b1072d84de4b9dd89d6d5caad98950aa193b7343b8e", + "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 +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-invalid/source.opy b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-invalid/source.opy new file mode 100644 index 00000000..fa509fb1 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-invalid/source.opy @@ -0,0 +1,4 @@ +macro p(): + 1 +macro p = eventPlayer +globalvar target = [p(), p] diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-safe/fixture.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-safe/fixture.json new file mode 100644 index 00000000..552373ff --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-safe/fixture.json @@ -0,0 +1,24 @@ +{ + "schemaVersion": 1, + "id": "synthetic/macro-first-constant-initializer-safe", + "category": "compilation", + "features": [ + "declaration initializers", + "event context", + "constant and callable macro namespaces" + ], + "source": "source.opy", + "tests": { + "source": { + "nativeStatus": "success", + "relationship": "match", + "ruleNames": true + }, + "compiler": { + "nativeStatus": "success", + "relationship": "match", + "comparison": "semantic-wir", + "semanticEquivalent": true + } + } +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-safe/oracle.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-safe/oracle.json new file mode 100644 index 00000000..e7d86e9c --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-safe/oracle.json @@ -0,0 +1,34 @@ +{ + "compile": { + "diagnostics": [], + "exitCode": 0, + "status": "success", + "stdout": "", + "workshop": "variables {\n global:\n 0: target\n player:\n 0: playerTarget\n}\n\nrule (\"Initialize global variables\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(target, 1);\n }\n}\n\nrule (\"Initialize player variables\") {\n event {\n Ongoing - Each Player;\n All;\n All;\n }\n actions {\n Set Player Variable(Event Player, playerTarget, Event Player);\n }\n}\n", + "workshopExact": "variables {\n global:\n 0: target\n player:\n 0: playerTarget\n}\n\nrule (\"Initialize global variables\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(target, 1);\n }\n}\n\nrule (\"Initialize player variables\") {\n event {\n Ongoing - Each Player;\n All;\n All;\n }\n actions {\n Set Player Variable(Event Player, playerTarget, Event Player);\n }\n}\n\n", + "workshopSha256": "31f5cdf794b0aac9089c83027ff555e374d2c6e6d0fa85140b98f3f3c51d2b77" + }, + "fixture": "synthetic/macro-first-constant-initializer-safe", + "input": { + "files": [ + { + "path": "source.opy", + "sha256": "21bb932cfd45ddb07a95d293aad1cd24770398a2b29d11b16ec7f1f0e10ec7bf" + } + ], + "sha256": "b59c3b43497e32060594625bb2b062bf3dfccfb3d25202354be20003cb5f5a2d", + "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 +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-safe/source.opy b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-safe/source.opy new file mode 100644 index 00000000..3075dfcd --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/macro-first-constant-initializer-safe/source.opy @@ -0,0 +1,5 @@ +macro p(): + eventPlayer +macro p = 1 +globalvar target = p +playervar playerTarget = p() diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus-assignment/fixture.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus-assignment/fixture.json new file mode 100644 index 00000000..2bbbc277 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus-assignment/fixture.json @@ -0,0 +1,25 @@ +{ + "schemaVersion": 1, + "id": "synthetic/unary-plus-assignment", + "category": "compilation", + "features": [ + "unary plus", + "operator precedence", + "declaration initializers", + "structural convergence" + ], + "source": "source.opy", + "tests": { + "source": { + "nativeStatus": "success", + "relationship": "match", + "ruleNames": true + }, + "compiler": { + "nativeStatus": "success", + "relationship": "match", + "comparison": "semantic-wir", + "semanticEquivalent": true + } + } +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus-assignment/oracle.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus-assignment/oracle.json new file mode 100644 index 00000000..656d8bb0 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus-assignment/oracle.json @@ -0,0 +1,34 @@ +{ + "compile": { + "diagnostics": [], + "exitCode": 0, + "status": "success", + "stdout": "", + "workshop": "variables {\n global:\n 0: x\n}\n\nrule (\"test\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(x, 2);\n Modify Global Variable(x, Add, 2);\n Set Global Variable(x, 2);\n Modify Global Variable(x, Add, 1);\n }\n}\n", + "workshopExact": "variables {\n global:\n 0: x\n}\n\nrule (\"test\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(x, 2);\n Modify Global Variable(x, Add, 2);\n Set Global Variable(x, 2);\n Modify Global Variable(x, Add, 1);\n }\n}\n\n", + "workshopSha256": "fbbc3b8800035726d8f34c63951a15cd37333a7b46f1b92f5fb4f868ffcb5579" + }, + "fixture": "synthetic/unary-plus-assignment", + "input": { + "files": [ + { + "path": "source.opy", + "sha256": "a372b6a52f8818639a12ec768ad1ef988ad934254aab402f0ef69621102b6db0" + } + ], + "sha256": "d9d0b31b6446719136779f1c6448e90d7071a480cb24453347e00928567d9d1d", + "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 +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus-assignment/source.opy b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus-assignment/source.opy new file mode 100644 index 00000000..76100422 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus-assignment/source.opy @@ -0,0 +1,6 @@ +globalvar x +rule "test": + ++x = 2 + ++x += 2 + +++x = 2 + ++x++ diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus/fixture.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus/fixture.json new file mode 100644 index 00000000..b2a14a53 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus/fixture.json @@ -0,0 +1,25 @@ +{ + "schemaVersion": 1, + "id": "synthetic/unary-plus", + "category": "compilation", + "features": [ + "unary plus", + "operator precedence", + "declaration initializers", + "structural convergence" + ], + "source": "source.opy", + "tests": { + "source": { + "nativeStatus": "success", + "relationship": "match", + "ruleNames": true + }, + "compiler": { + "nativeStatus": "success", + "relationship": "match", + "comparison": "semantic-wir", + "semanticEquivalent": true + } + } +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus/oracle.json b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus/oracle.json new file mode 100644 index 00000000..6deba094 --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus/oracle.json @@ -0,0 +1,34 @@ +{ + "compile": { + "diagnostics": [], + "exitCode": 0, + "status": "success", + "stdout": "", + "workshop": "variables {\n global:\n 0: initial\n 1: result\n player:\n 0: target\n}\n\nrule (\"Initialize global variables\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(initial, 1);\n }\n}\n\nrule (\"Initialize player variables\") {\n event {\n Ongoing - Each Player;\n All;\n All;\n }\n actions {\n Set Player Variable(Event Player, target, Event Player);\n }\n}\n\nrule (\"unary plus\") {\n event {\n Ongoing - Each Player;\n All;\n All;\n }\n actions {\n Set Global Variable(result, 1);\n Set Global Variable(result, Event Player);\n Set Global Variable(result, Vector(1, 2, 3));\n Set Global Variable(result, Multiply(Add(Global.result, 2), 3));\n Set Global Variable(result, 8);\n Modify Global Variable(result, Raise To Power, 2);\n Set Global Variable(result, Multiply(-1, Global.result));\n Set Global Variable(result, Add(1, Global.result));\n Set Global Variable(result, 1);\n Set Global Variable(result, 1);\n Set Global Variable(result, Add(1, Global.result));\n Set Global Variable(result, Add(1, Multiply(Global.result, 2)));\n Set Global Variable(result, True);\n Set Global Variable(result, Custom String(\"x\"));\n Modify Global Variable(result, Add, 1);\n }\n}\n", + "workshopExact": "variables {\n global:\n 0: initial\n 1: result\n player:\n 0: target\n}\n\nrule (\"Initialize global variables\") {\n event {\n Ongoing - Global;\n }\n actions {\n Set Global Variable(initial, 1);\n }\n}\n\nrule (\"Initialize player variables\") {\n event {\n Ongoing - Each Player;\n All;\n All;\n }\n actions {\n Set Player Variable(Event Player, target, Event Player);\n }\n}\n\nrule (\"unary plus\") {\n event {\n Ongoing - Each Player;\n All;\n All;\n }\n actions {\n Set Global Variable(result, 1);\n Set Global Variable(result, Event Player);\n Set Global Variable(result, Vector(1, 2, 3));\n Set Global Variable(result, Multiply(Add(Global.result, 2), 3));\n Set Global Variable(result, 8);\n Modify Global Variable(result, Raise To Power, 2);\n Set Global Variable(result, Multiply(-1, Global.result));\n Set Global Variable(result, Add(1, Global.result));\n Set Global Variable(result, 1);\n Set Global Variable(result, 1);\n Set Global Variable(result, Add(1, Global.result));\n Set Global Variable(result, Add(1, Multiply(Global.result, 2)));\n Set Global Variable(result, True);\n Set Global Variable(result, Custom String(\"x\"));\n Modify Global Variable(result, Add, 1);\n }\n}\n\n", + "workshopSha256": "d01dd8f63d63f2b72319efb2759ac1776123c94c8a8292ef75f6522b0946b81c" + }, + "fixture": "synthetic/unary-plus", + "input": { + "files": [ + { + "path": "source.opy", + "sha256": "b6aaaf8e96a4f047d8fbc07a4af9803353ff824c6173fd7f4b7db2702a2895d3" + } + ], + "sha256": "2201b4341216c8bae46627423e53f91db50d9d8784f205ee7d6600bec804f5ff", + "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 +} diff --git a/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus/source.opy b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus/source.opy new file mode 100644 index 00000000..fc6d75cb --- /dev/null +++ b/crates/opy-rs/tests/fixtures/corpus/synthetic/unary-plus/source.opy @@ -0,0 +1,22 @@ +playervar target = +eventPlayer +globalvar initial = +1 +globalvar result +rule "unary plus": + @Event eachPlayer + result = +1 + result = +result + result = +eventPlayer + result = +vect(1, 2, 3) + result = +(result + 2) * 3 + result = 2 ** +3 + result = +result ** 2 + result = +-result + result = +(+result) + result = 1 + +result + result = ++1 + result = +++1 + result = 1++result + result = 1++result * 2 + result = +true + result = +"x" + result++