From d933f00be208a586143b35d06e689f94a6a6f7e6 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sun, 31 Oct 2021 02:06:07 +0100 Subject: feat(web): client support for transformation rules --- language-web/src/main/js/editor/EditorParent.ts | 2 +- language-web/src/main/js/index.tsx | 7 +++++ language-web/src/main/js/language/folding.ts | 30 +++++++++++++++++----- language-web/src/main/js/language/indentation.ts | 5 +++- language-web/src/main/js/language/problem.grammar | 26 +++++++++++++++---- .../src/main/js/language/problemLanguageSupport.ts | 18 ++++++++----- 6 files changed, 69 insertions(+), 19 deletions(-) (limited to 'language-web/src') diff --git a/language-web/src/main/js/editor/EditorParent.ts b/language-web/src/main/js/editor/EditorParent.ts index b890ac3c..ee1323f6 100644 --- a/language-web/src/main/js/editor/EditorParent.ts +++ b/language-web/src/main/js/editor/EditorParent.ts @@ -127,7 +127,7 @@ export const EditorParent = styled('div')(({ theme }) => { '.cmt-keyword': { color: theme.palette.primary.main, }, - '.cmt-typeName, .cmt-atom': { + '.cmt-typeName, .cmt-macroName, .cmt-atom': { color: theme.palette.text.primary, }, '.cmt-variableName': { diff --git a/language-web/src/main/js/index.tsx b/language-web/src/main/js/index.tsx index 595498fc..dfecde37 100644 --- a/language-web/src/main/js/index.tsx +++ b/language-web/src/main/js/index.tsx @@ -31,6 +31,13 @@ pred invalidTaxStatus(Person p) <-> parent(p, q), !taxStatus(q, retired). +direct rule createChild(p): + children(p, newPerson) = unknown, + equals(newPerson, newPerson) = unknown + ~> new q, + children(p, q) = true, + taxStatus(q, child) = true. + unique family. Family(family). members(family, anne). diff --git a/language-web/src/main/js/language/folding.ts b/language-web/src/main/js/language/folding.ts index 54c7294d..5d51f796 100644 --- a/language-web/src/main/js/language/folding.ts +++ b/language-web/src/main/js/language/folding.ts @@ -75,18 +75,22 @@ export function foldDeclaration(node: SyntaxNode, state: EditorState): FoldRange * @param node the node to fold * @returns the folding range or `null` is there is nothing to fold */ -export function foldConjunction(node: SyntaxNode): FoldRange | null { +function foldWithSibling(node: SyntaxNode): FoldRange | null { const { parent } = node; if (parent === null) { return null; } - const { cursor } = parent; - let nConjunctions = 0; - while (cursor.next()) { + const { firstChild } = parent; + if (firstChild === null) { + return null; + } + const { cursor } = firstChild; + let nSiblings = 0; + while (cursor.nextSibling()) { if (cursor.type === node.type) { - nConjunctions += 1; + nSiblings += 1; } - if (nConjunctions >= 2) { + if (nSiblings >= 2) { return { from: node.from, to: node.to, @@ -95,3 +99,17 @@ export function foldConjunction(node: SyntaxNode): FoldRange | null { } return null; } + +export function foldWholeNode(node: SyntaxNode): FoldRange { + return { + from: node.from, + to: node.to, + }; +} + +export function foldConjunction(node: SyntaxNode): FoldRange | null { + if (node.parent?.type?.name === 'PredicateBody') { + return foldWithSibling(node); + } + return foldWholeNode(node); +} diff --git a/language-web/src/main/js/language/indentation.ts b/language-web/src/main/js/language/indentation.ts index 973b4a80..78f0a750 100644 --- a/language-web/src/main/js/language/indentation.ts +++ b/language-web/src/main/js/language/indentation.ts @@ -75,10 +75,13 @@ export function indentDeclaration(context: TreeIndentContext): number { return indentDeclarationStrategy(context, 1); } -export function indentPredicate(context: TreeIndentContext): number { +export function indentPredicateOrRule(context: TreeIndentContext): number { const clauseIndent = indentDeclarationStrategy(context, 1); if (/^\s+(;|\.)/.exec(context.textAfter) !== null) { return clauseIndent - 2; } + if (/^\s+(~>)/.exec(context.textAfter) !== null) { + return clauseIndent - 3; + } return clauseIndent; } diff --git a/language-web/src/main/js/language/problem.grammar b/language-web/src/main/js/language/problem.grammar index cf940698..c242a4ba 100644 --- a/language-web/src/main/js/language/problem.grammar +++ b/language-web/src/main/js/language/problem.grammar @@ -14,9 +14,15 @@ statement { (EnumBody { "{" sep<",", UniqueNodeName> "}" } | ".") } | PredicateDefinition { - (ckw<"error"> ckw<"pred">? | ckw<"pred">) RelationName ParameterList? + (ckw<"error"> ckw<"pred">? | ckw<"direct">? ckw<"pred">) + RelationName ParameterList? PredicateBody { ("<->" sep)? "." } } | + RuleDefinition { + ckw<"direct">? ckw<"rule"> + RuleName ParameterList? + RuleBody { ":" sep "~>" sep "." } + } | Assertion { ckw<"default">? (NotOp | UnknownOp)? RelationName ParameterList (":" LogicValue)? "." @@ -47,9 +53,17 @@ Conjunction { ("," | Literal)+ } OrOp { ";" } -Literal { NotOp? Atom } +Literal { NotOp? Atom (("=" | ":") sep1<"|", LogicValue>)? } + +Atom { RelationName "+"? ParameterList } -Atom { RelationName ParameterList? } +Action { ("," | ActionLiteral)+ } + +ActionLiteral { + ckw<"new"> VariableName | + ckw<"delete"> VariableName | + Literal +} Argument { VariableName | Constant } @@ -67,6 +81,8 @@ Multiplicity { (IntMult "..")? (IntMult | StarMult)} RelationName { QualifiedName } +RuleName { QualifiedName } + UniqueNodeName { QualifiedName } VariableName { QualifiedName } @@ -83,7 +99,7 @@ ParameterList { "(" sep<",", content> ")" } sep { sep1? } -sep1 { content (separator content?)* } +sep1 { content (separator content)* } @skip { LineComment | BlockComment | whitespace } @@ -123,7 +139,7 @@ sep1 { content (separator content?)* } StarArgument { "*" } - "{" "}" "(" ")" "[" "]" "." ".." "," ":" "<->" + "{" "}" "(" ")" "[" "]" "." ".." "," ":" "<->" "~>" } @detectDelim diff --git a/language-web/src/main/js/language/problemLanguageSupport.ts b/language-web/src/main/js/language/problemLanguageSupport.ts index 80d25d71..ab1c55f9 100644 --- a/language-web/src/main/js/language/problemLanguageSupport.ts +++ b/language-web/src/main/js/language/problemLanguageSupport.ts @@ -14,11 +14,12 @@ import { foldBlockComment, foldConjunction, foldDeclaration, + foldWholeNode, } from './folding'; import { indentBlockComment, indentDeclaration, - indentPredicate, + indentPredicateOrRule, } from './indentation'; const parserWithMetadata = (parser as LRParser).configure({ @@ -26,9 +27,10 @@ const parserWithMetadata = (parser as LRParser).configure({ styleTags({ LineComment: t.lineComment, BlockComment: t.blockComment, - 'problem class enum pred unique scope': t.definitionKeyword, - 'abstract extends refers contains opposite error default': t.modifier, + 'problem class enum pred rule unique scope': t.definitionKeyword, + 'abstract extends refers contains opposite error direct default': t.modifier, 'true false unknown error': t.keyword, + 'new delete': t.operatorKeyword, NotOp: t.keyword, UnknownOp: t.keyword, OrOp: t.keyword, @@ -37,19 +39,21 @@ const parserWithMetadata = (parser as LRParser).configure({ StarMult: t.number, String: t.string, 'RelationName/QualifiedName': t.typeName, + 'RuleName/QualifiedName': t.macroName, 'UniqueNodeName/QualifiedName': t.atom, 'VariableName/QualifiedName': t.variableName, '{ }': t.brace, '( )': t.paren, '[ ]': t.squareBracket, '. .. , :': t.separator, - '<->': t.definitionOperator, + '<-> ~>': t.definitionOperator, }), indentNodeProp.add({ ProblemDeclaration: indentDeclaration, UniqueDeclaration: indentDeclaration, ScopeDeclaration: indentDeclaration, - PredicateBody: indentPredicate, + PredicateBody: indentPredicateOrRule, + RuleBody: indentPredicateOrRule, BlockComment: indentBlockComment, }), foldNodeProp.add({ @@ -57,7 +61,9 @@ const parserWithMetadata = (parser as LRParser).configure({ EnumBody: foldInside, ParameterList: foldInside, PredicateBody: foldInside, + RuleBody: foldInside, Conjunction: foldConjunction, + Action: foldWholeNode, UniqueDeclaration: foldDeclaration, ScopeDeclaration: foldDeclaration, BlockComment: foldBlockComment, @@ -75,7 +81,7 @@ const problemLanguage = LRLanguage.define({ }, line: '%', }, - indentOnInput: /^\s*(?:\{|\}|\(|\)|;|\.)$/, + indentOnInput: /^\s*(?:\{|\}|\(|\)|;|\.|~>)$/, }, }); -- cgit v1.2.3-54-g00ecf