diff --git a/build/CodeLite/Notepad4.project b/build/CodeLite/Notepad4.project index 3b01dab4c2..9b520535cf 100644 --- a/build/CodeLite/Notepad4.project +++ b/build/CodeLite/Notepad4.project @@ -26,6 +26,7 @@ + @@ -212,6 +213,7 @@ + diff --git a/build/VS2017/Notepad4.vcxproj b/build/VS2017/Notepad4.vcxproj index 345b07c93f..8e8f2d7510 100644 --- a/build/VS2017/Notepad4.vcxproj +++ b/build/VS2017/Notepad4.vcxproj @@ -485,6 +485,7 @@ + @@ -614,6 +615,7 @@ + diff --git a/build/VS2017/Notepad4.vcxproj.filters b/build/VS2017/Notepad4.vcxproj.filters index 381b14801d..4b242d4ddb 100644 --- a/build/VS2017/Notepad4.vcxproj.filters +++ b/build/VS2017/Notepad4.vcxproj.filters @@ -63,6 +63,9 @@ Scintilla\lexers + + Scintilla\lexers + Scintilla\lexers @@ -450,6 +453,9 @@ Source Files\EditLexers + + Source Files\EditLexers + Source Files\EditLexers diff --git a/doc/FileExt.txt b/doc/FileExt.txt index d6eee7e6d1..282a2e1c6f 100644 --- a/doc/FileExt.txt +++ b/doc/FileExt.txt @@ -223,6 +223,9 @@ blockdiag diag +Cangjie Source + cj + CIL Assembly il diff --git a/doc/Notepad4 DarkTheme.ini b/doc/Notepad4 DarkTheme.ini index 69794891d8..45469b90e2 100644 --- a/doc/Notepad4 DarkTheme.ini +++ b/doc/Notepad4 DarkTheme.ini @@ -142,6 +142,11 @@ Operator=fore:#A349A4 Keyword=fore:#00B050 Number=fore:#F84C4C Operator=fore:#A349A4 +[Cangjie Source] +Keyword=fore:#00B050 +Type Keyword=fore:#00B050 +Number=fore:#F84C4C +Operator=fore:#A349A4 [CIL Assembly] Keyword=fore:#00B050 Type Keyword=fore:#00B050 diff --git a/readme.md b/readme.md index 9072866095..2ac37eec00 100644 --- a/readme.md +++ b/readme.md @@ -50,6 +50,7 @@ Latest development builds (artifacts in Release configuration for each compiler * Objective-C/C++, [Screenshots](https://github.com/zufuliu/notepad4/wiki/Screenshots#objective-cc) * [C Standard Library](tools/lang/C.c), up to C2x. * [C++ STL](tools/lang/CPP.cpp), up to C++20. + * [Cangjie (仓颉)](tools/lang/Cangjie.cj), up to June 2024. * [CSS Style Sheet](tools/lang/CSS.css), up to December 2023 snapshot. * [SCSS Style Sheet](tools/lang/SCSS.scss), up to Dart Sass 1.50. * [Less Style Sheet](tools/lang/Less.less), up to Less 4.1. diff --git a/scintilla/include/SciLexer.h b/scintilla/include/SciLexer.h index c973f6fcee..f848131598 100644 --- a/scintilla/include/SciLexer.h +++ b/scintilla/include/SciLexer.h @@ -98,6 +98,7 @@ #define SCLEX_ZIG 224 #define SCLEX_MATHEMATICA 225 #define SCLEX_WINHEX 226 +#define SCLEX_CANGJIE 227 #define SCLEX_AUTOMATIC 1000 #define SCE_PY_DEFAULT 0 #define SCE_PY_COMMENTLINE 1 @@ -1864,4 +1865,36 @@ #define SCE_WINHEX_KEYWORD 7 #define SCE_WINHEX_TYPE 8 #define SCE_WINHEX_COMMAND 9 +#define SCE_CANGJIE_DEFAULT 0 +#define SCE_CANGJIE_COMMENTLINE 1 +#define SCE_CANGJIE_COMMENTLINEDOC 2 +#define SCE_CANGJIE_COMMENTBLOCK 3 +#define SCE_CANGJIE_COMMENTBLOCKDOC 4 +#define SCE_CANGJIE_TASKMARKER 5 +#define SCE_CANGJIE_NUMBER 6 +#define SCE_CANGJIE_IDENTIFIER 7 +#define SCE_CANGJIE_IDENTIFIER_BT 8 +#define SCE_CANGJIE_MACRO 9 +#define SCE_CANGJIE_VARIABLE 10 +#define SCE_CANGJIE_STRING_SQ 11 +#define SCE_CANGJIE_STRING_DQ 12 +#define SCE_CANGJIE_TRIPLE_STRING_SQ 13 +#define SCE_CANGJIE_TRIPLE_STRING_DQ 14 +#define SCE_CANGJIE_RUNE_SQ 15 +#define SCE_CANGJIE_RUNE_DQ 16 +#define SCE_CANGJIE_RAWSTRING_SQ 17 +#define SCE_CANGJIE_RAWSTRING_DQ 18 +#define SCE_CANGJIE_ESCAPECHAR 19 +#define SCE_CANGJIE_OPERATOR 20 +#define SCE_CANGJIE_OPERATOR2 21 +#define SCE_CANGJIE_WORD 22 +#define SCE_CANGJIE_WORD2 23 +#define SCE_CANGJIE_TYPE 24 +#define SCE_CANGJIE_ANNOTATION 25 +#define SCE_CANGJIE_CLASS 26 +#define SCE_CANGJIE_STRUCT 27 +#define SCE_CANGJIE_INTERFACE 28 +#define SCE_CANGJIE_ENUM 29 +#define SCE_CANGJIE_FUNCTION_DEFINITION 30 +#define SCE_CANGJIE_FUNCTION 31 /* --Autogenerated -- end of section automatically generated from SciLexer.iface */ diff --git a/scintilla/include/SciLexer.iface b/scintilla/include/SciLexer.iface index 5b41076a60..e00c4ae85a 100644 --- a/scintilla/include/SciLexer.iface +++ b/scintilla/include/SciLexer.iface @@ -171,6 +171,7 @@ val SCLEX_CSV=223 val SCLEX_ZIG=224 val SCLEX_MATHEMATICA=225 val SCLEX_WINHEX=226 +val SCLEX_CANGJIE=227 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -3173,3 +3174,37 @@ val SCE_WINHEX_IDENTIFIER= val SCE_WINHEX_KEYWORD= val SCE_WINHEX_TYPE= val SCE_WINHEX_COMMAND= +# Lexical states for SCLEX_CANGJIE +lex Cangjie=SCLEX_CANGJIE SCE_CANGJIE_ +val SCE_CANGJIE_DEFAULT= +val SCE_CANGJIE_COMMENTLINE= +val SCE_CANGJIE_COMMENTLINEDOC= +val SCE_CANGJIE_COMMENTBLOCK= +val SCE_CANGJIE_COMMENTBLOCKDOC= +val SCE_CANGJIE_TASKMARKER= +val SCE_CANGJIE_NUMBER= +val SCE_CANGJIE_IDENTIFIER= +val SCE_CANGJIE_IDENTIFIER_BT= +val SCE_CANGJIE_MACRO= +val SCE_CANGJIE_VARIABLE= +val SCE_CANGJIE_STRING_SQ=11 +val SCE_CANGJIE_STRING_DQ=12 +val SCE_CANGJIE_TRIPLE_STRING_SQ=13 +val SCE_CANGJIE_TRIPLE_STRING_DQ=14 +val SCE_CANGJIE_RUNE_SQ= +val SCE_CANGJIE_RUNE_DQ= +val SCE_CANGJIE_RAWSTRING_SQ= +val SCE_CANGJIE_RAWSTRING_DQ= +val SCE_CANGJIE_ESCAPECHAR= +val SCE_CANGJIE_OPERATOR= +val SCE_CANGJIE_OPERATOR2= +val SCE_CANGJIE_WORD= +val SCE_CANGJIE_WORD2= +val SCE_CANGJIE_TYPE= +val SCE_CANGJIE_ANNOTATION= +val SCE_CANGJIE_CLASS= +val SCE_CANGJIE_STRUCT= +val SCE_CANGJIE_INTERFACE= +val SCE_CANGJIE_ENUM= +val SCE_CANGJIE_FUNCTION_DEFINITION= +val SCE_CANGJIE_FUNCTION= diff --git a/scintilla/lexers/LexCangjie.cxx b/scintilla/lexers/LexCangjie.cxx new file mode 100644 index 0000000000..1e3b633acd --- /dev/null +++ b/scintilla/lexers/LexCangjie.cxx @@ -0,0 +1,522 @@ +// This file is part of Notepad4. +// See License.txt for details about distribution and modification. +//! Lexer for Cangjie. + +#include +#include + +#include +#include +#include + +#include "ILexer.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#include "WordList.h" +#include "LexAccessor.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "CharacterSet.h" +#include "StringUtils.h" +#include "LexerModule.h" +#include "LexerUtils.h" + +using namespace Lexilla; + +namespace { + +struct EscapeSequence { + int outerState = SCE_CANGJIE_DEFAULT; + int digitsLeft = 0; + bool brace = false; + + // highlight any character as escape sequence. + bool resetEscapeState(int state, int chNext) noexcept { + if (IsEOLChar(chNext)) { + return false; + } + outerState = state; + brace = false; + digitsLeft = 1; + return true; + } + bool atEscapeEnd(int ch) noexcept { + --digitsLeft; + return digitsLeft <= 0 || !IsHexDigit(ch); + } +}; + +enum { + CangjieLineStateMaskLineComment = 1, // line comment + CangjieLineStateMaskImport = (1 << 1), // import +}; + +//KeywordIndex++Autogenerated -- start of section automatically generated +enum { + KeywordIndex_Keyword = 0, + KeywordIndex_Type = 1, + KeywordIndex_Annotation = 3, + KeywordIndex_Class = 4, + KeywordIndex_Struct = 5, + KeywordIndex_Interface = 6, + KeywordIndex_Enumeration = 7, +}; +//KeywordIndex--Autogenerated -- end of section automatically generated + +enum class KeywordType { + None = SCE_CANGJIE_DEFAULT, + Type = SCE_CANGJIE_TYPE, + Class = SCE_CANGJIE_CLASS, + Struct = SCE_CANGJIE_STRUCT, + Interface = SCE_CANGJIE_INTERFACE, + Enum = SCE_CANGJIE_ENUM, + Function = SCE_CANGJIE_FUNCTION_DEFINITION, +}; + +static_assert(DefaultNestedStateBaseStyle + 1 == SCE_CANGJIE_STRING_SQ); +static_assert(DefaultNestedStateBaseStyle + 2 == SCE_CANGJIE_STRING_DQ); +static_assert(DefaultNestedStateBaseStyle + 3 == SCE_CANGJIE_TRIPLE_STRING_SQ); +static_assert(DefaultNestedStateBaseStyle + 4 == SCE_CANGJIE_TRIPLE_STRING_DQ); + +constexpr bool IsSpaceEquiv(int state) noexcept { + return state <= SCE_CANGJIE_TASKMARKER; +} + +constexpr bool IsTripleString(int state) noexcept { + return state == SCE_CANGJIE_TRIPLE_STRING_SQ || state == SCE_CANGJIE_TRIPLE_STRING_DQ; +} + +constexpr int GetStringQuote(int state) noexcept { + if constexpr (SCE_CANGJIE_STRING_SQ & 1) { + return (state & 1) ? '\'' : '\"'; + } else { + return (state & 1) ? '\"' : '\''; + } +} + +void ColouriseCangjieDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, LexerWordList keywordLists, Accessor &styler) { + int lineStateLineType = 0; + int commentLevel = 0; // nested block comment level + + KeywordType kwType = KeywordType::None; + int chBeforeIdentifier = 0; + + int delimiterCount = 0; // count of '#' + std::vector nestedState; // string interpolation "${}" + + int visibleChars = 0; + int visibleCharsBefore = 0; + int chPrevNonWhite = 0; + EscapeSequence escSeq; + + StyleContext sc(startPos, lengthDoc, initStyle, styler); + if (sc.currentLine > 0) { + int lineState = styler.GetLineState(sc.currentLine - 1); + /* + 2: lineStateLineType + 6: commentLevel + 8: delimiterCount + 3: nestedState count + 3*4: nestedState + */ + commentLevel = (lineState >> 2) & 0x3f; + delimiterCount = (lineState >> 8) & 0xff; + lineState >>= 16; + if (lineState) { + UnpackLineState(lineState, nestedState); + } + } + + while (sc.More()) { + switch (sc.state) { + case SCE_CANGJIE_OPERATOR: + case SCE_CANGJIE_OPERATOR2: + sc.SetState(SCE_CANGJIE_DEFAULT); + break; + + case SCE_CANGJIE_NUMBER: + if (!IsDecimalNumberEx(sc.chPrev, sc.ch, sc.chNext)) { + sc.SetState(SCE_CANGJIE_DEFAULT); + } + break; + + case SCE_CANGJIE_IDENTIFIER: + case SCE_CANGJIE_IDENTIFIER_BT: + case SCE_CANGJIE_MACRO: + case SCE_CANGJIE_VARIABLE: + if (!IsIdentifierChar(sc.ch)) { + if (sc.state == SCE_CANGJIE_IDENTIFIER_BT) { + if (sc.ch == '`') { + sc.Forward(); + } + } else if (sc.state != SCE_CANGJIE_VARIABLE) { + char s[128]; + sc.GetCurrent(s, sizeof(s)); + if (sc.state == SCE_CANGJIE_MACRO) { + // TODO: prefer annotation when next line is class definition + if (keywordLists[KeywordIndex_Annotation].InList(s + 1)) { + sc.ChangeState(SCE_CANGJIE_ANNOTATION); + } + } else { + if (keywordLists[KeywordIndex_Keyword].InList(s)) { + sc.ChangeState(SCE_CANGJIE_WORD); + if (StrEqualsAny(s, "import")) { + if (visibleChars == sc.LengthCurrent()) { + lineStateLineType = CangjieLineStateMaskImport; + } + } else if (StrEqualsAny(s, "class", "extend", "throw", "as", "is")) { + if (lineStateLineType != CangjieLineStateMaskImport) { + // import as + kwType = KeywordType::Class; + } + } else if (StrEqual(s, "struct")) { + kwType = KeywordType::Struct; + } else if (StrEqual(s, "interface")) { + kwType = KeywordType::Interface; + } else if (StrEqual(s, "enum")) { + kwType = KeywordType::Enum; + } else if (StrEqualsAny(s, "func", "macro")) { + kwType = KeywordType::Function; + } else if (StrEqual(s, "type")) { + kwType = KeywordType::Type; // type alias + } + if (kwType != KeywordType::None) { + const int chNext = sc.GetLineNextChar(); + if (!IsIdentifierStart(chNext)) { + kwType = KeywordType::None; + } + } + } else if (keywordLists[KeywordIndex_Type].InList(s)) { + sc.ChangeState(SCE_CANGJIE_WORD2); + } else if (keywordLists[KeywordIndex_Class].InList(s)) { + sc.ChangeState(SCE_CANGJIE_CLASS); + } else if (keywordLists[KeywordIndex_Struct].InList(s)) { + sc.ChangeState(SCE_CANGJIE_STRUCT); + } else if (keywordLists[KeywordIndex_Interface].InList(s)) { + sc.ChangeState(SCE_CANGJIE_INTERFACE); + } else if (keywordLists[KeywordIndex_Enumeration].InList(s)) { + sc.ChangeState(SCE_CANGJIE_ENUM); + } + } + } + if (sc.state == SCE_CANGJIE_IDENTIFIER || sc.state == SCE_CANGJIE_IDENTIFIER_BT) { + if (sc.ch != '.') { + if (kwType != KeywordType::None) { + sc.ChangeState(static_cast(kwType)); + } else { + const int chNext = sc.GetLineNextChar(); + if (chNext == '(') { + sc.ChangeState(SCE_CANGJIE_FUNCTION); + } else if ((chBeforeIdentifier == '<' && (chNext == '>' || chNext == '<'))) { + // type + // type> + // type + sc.ChangeState(SCE_CANGJIE_CLASS); + } + } + } + } + if (sc.state != SCE_CANGJIE_WORD && sc.ch != '.') { + kwType = KeywordType::None; + } + sc.SetState(SCE_CANGJIE_DEFAULT); + } + break; + + case SCE_CANGJIE_COMMENTLINE: + case SCE_CANGJIE_COMMENTLINEDOC: + if (sc.atLineStart) { + sc.SetState(SCE_CANGJIE_DEFAULT); + } else { + HighlightTaskMarker(sc, visibleChars, visibleCharsBefore, SCE_CANGJIE_TASKMARKER); + } + break; + + case SCE_CANGJIE_COMMENTBLOCK: + case SCE_CANGJIE_COMMENTBLOCKDOC: + if (sc.Match('*', '/')) { + sc.Forward(); + --commentLevel; + if (commentLevel == 0) { + sc.ForwardSetState(SCE_CANGJIE_DEFAULT); + } + } else if (sc.Match('/', '*')) { + sc.Forward(); + ++commentLevel; + } else if (HighlightTaskMarker(sc, visibleChars, visibleCharsBefore, SCE_CANGJIE_TASKMARKER)) { + continue; + } + break; + + case SCE_CANGJIE_RUNE_SQ: + case SCE_CANGJIE_RUNE_DQ: + case SCE_CANGJIE_STRING_SQ: + case SCE_CANGJIE_STRING_DQ: + case SCE_CANGJIE_TRIPLE_STRING_SQ: + case SCE_CANGJIE_TRIPLE_STRING_DQ: + if (sc.atLineStart && !IsTripleString(sc.state)) { + sc.SetState(SCE_CANGJIE_DEFAULT); + } else if (sc.ch == '\\') { + if (escSeq.resetEscapeState(sc.state, sc.chNext)) { + sc.SetState(SCE_CANGJIE_ESCAPECHAR); + sc.Forward(); + if (sc.Match('u', '{')) { + escSeq.brace = true; + escSeq.digitsLeft = 9; + sc.Forward(); + } + } + } else if (sc.Match('$', '{') && sc.state < SCE_CANGJIE_RUNE_SQ) { + nestedState.push_back(sc.state); + sc.SetState(SCE_CANGJIE_OPERATOR2); + sc.Forward(); + } else if (sc.ch == GetStringQuote(sc.state) && (!IsTripleString(sc.state) || sc.MatchNext())) { + if (IsTripleString(sc.state)) { + sc.Advance(2); + } + sc.ForwardSetState(SCE_CANGJIE_DEFAULT); + } + break; + + case SCE_CANGJIE_RAWSTRING_SQ: + case SCE_CANGJIE_RAWSTRING_DQ: + if (sc.chNext == '#' && sc.ch == GetStringQuote(sc.state)) { + int count = delimiterCount; + do { + sc.Forward(); + --count; + } while (count != 0 && sc.ch == '#'); + if (count == 0) { + delimiterCount = 0; + sc.ForwardSetState(SCE_CANGJIE_DEFAULT); + } + } + break; + + case SCE_CANGJIE_ESCAPECHAR: + if (escSeq.atEscapeEnd(sc.ch)) { + if (escSeq.brace && sc.ch == '}') { + sc.Forward(); + } + sc.SetState(escSeq.outerState); + continue; + } + break; + } + + if (sc.state == SCE_CANGJIE_DEFAULT) { + if (sc.ch == '/' && (sc.chNext == '/' || sc.chNext == '*')) { + visibleCharsBefore = visibleChars; + const int chNext = sc.chNext; + sc.SetState((chNext == '/') ? SCE_CANGJIE_COMMENTLINE : SCE_CANGJIE_COMMENTBLOCK); + sc.Forward(2); + if (sc.ch == chNext && sc.chNext != chNext) { + sc.ChangeState((chNext == '/') ? SCE_CANGJIE_COMMENTLINEDOC : SCE_CANGJIE_COMMENTBLOCKDOC); + } + if (chNext == '/') { + if (visibleChars == 0) { + lineStateLineType = CangjieLineStateMaskLineComment; + } + } else { + commentLevel = 1; + } + continue; + } + if (sc.ch == 'r' && (sc.chNext == '\'' || sc.chNext == '"')) { + sc.SetState((sc.chNext == '\'') ? SCE_CANGJIE_RUNE_SQ : SCE_CANGJIE_RUNE_DQ); + sc.Forward(); + } else if (sc.ch == '"') { + if (sc.MatchNext('"', '"')) { + sc.SetState(SCE_CANGJIE_TRIPLE_STRING_DQ); + sc.Advance(2); + } else { + sc.SetState(SCE_CANGJIE_STRING_DQ); + } + } else if (sc.ch == '\'') { + if (sc.MatchNext('\'', '\'')) { + sc.SetState(SCE_CANGJIE_TRIPLE_STRING_SQ); + sc.Advance(2); + } else { + sc.SetState(SCE_CANGJIE_STRING_SQ); + } + } else if (IsNumberStartEx(sc.chPrev, sc.ch, sc.chNext)) { + sc.SetState(SCE_CANGJIE_NUMBER); + } else if (sc.ch == '@' && IsIdentifierStart(sc.chNext)) { + sc.SetState(SCE_CANGJIE_MACRO); + } else if (sc.ch == '$' && IsIdentifierChar(sc.chNext)) { + sc.SetState(SCE_CANGJIE_VARIABLE); + } else if (IsIdentifierStart(sc.ch) || (sc.ch == '`' && IsIdentifierStart(sc.chNext))) { + if (chPrevNonWhite != '.') { + chBeforeIdentifier = chPrevNonWhite; + } + sc.SetState((sc.ch == '`') ? SCE_CANGJIE_IDENTIFIER_BT : SCE_CANGJIE_IDENTIFIER); + } else if (sc.ch == '#') { + sc.SetState(SCE_CANGJIE_OPERATOR); + int count = 1; + while (sc.chNext == '#') { + ++count; + sc.Forward(); + } + if (sc.chNext == '\'' || sc.chNext == '"') { + delimiterCount = count; + sc.ChangeState((sc.chNext == '\'') ? SCE_CANGJIE_RUNE_SQ : SCE_CANGJIE_RAWSTRING_DQ); + sc.Forward(); + } + } else if (IsAGraphic(sc.ch)) { + sc.SetState(SCE_CANGJIE_OPERATOR); + if (sc.Match('<', ':')) { + kwType = KeywordType::Class; + } + if (!nestedState.empty()) { + sc.ChangeState(SCE_CANGJIE_OPERATOR2); + if (sc.ch == '{') { + nestedState.push_back(SCE_CANGJIE_DEFAULT); + } else if (sc.ch == '}') { + const int outerState = TakeAndPop(nestedState); + sc.ForwardSetState(outerState); + continue; + } + } + } + } + + if (!isspacechar(sc.ch)) { + visibleChars++; + if (!IsSpaceEquiv(sc.state)) { + chPrevNonWhite = sc.ch; + } + } + if (sc.atLineEnd) { + int lineState = (commentLevel << 2) | (delimiterCount << 8) | lineStateLineType; + if (!nestedState.empty()) { + lineState |= PackLineState(nestedState) << 16; + } + styler.SetLineState(sc.currentLine, lineState); + lineStateLineType = 0; + visibleChars = 0; + visibleCharsBefore = 0; + kwType = KeywordType::None; + } + sc.Forward(); + } + + sc.Complete(); +} + +struct FoldLineState { + int lineComment; + int packageImport; + constexpr explicit FoldLineState(int lineState) noexcept: + lineComment(lineState & CangjieLineStateMaskLineComment), + packageImport((lineState >> 1) & 1) { + } +}; + +void FoldCangjieDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, LexerWordList /*keywordLists*/, Accessor &styler) { + const Sci_PositionU endPos = startPos + lengthDoc; + Sci_Line lineCurrent = styler.GetLine(startPos); + FoldLineState foldPrev(0); + int levelCurrent = SC_FOLDLEVELBASE; + if (lineCurrent > 0) { + levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16; + foldPrev = FoldLineState(styler.GetLineState(lineCurrent - 1)); + const Sci_PositionU bracePos = CheckBraceOnNextLine(styler, lineCurrent - 1, SCE_CANGJIE_OPERATOR, SCE_CANGJIE_TASKMARKER); + if (bracePos) { + startPos = bracePos + 1; // skip the brace + } + } + + int levelNext = levelCurrent; + FoldLineState foldCurrent(styler.GetLineState(lineCurrent)); + Sci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1); + lineStartNext = sci::min(lineStartNext, endPos); + + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + int style = initStyle; + int visibleChars = 0; + + while (startPos < endPos) { + const char ch = chNext; + const int stylePrev = style; + style = styleNext; + chNext = styler[++startPos]; + styleNext = styler.StyleAt(startPos); + + switch (style) { + case SCE_CANGJIE_COMMENTBLOCKDOC: + case SCE_CANGJIE_COMMENTBLOCK: { + const int level = (ch == '/' && chNext == '*') ? 1 : ((ch == '*' && chNext == '/') ? -1 : 0); + if (level != 0) { + levelNext += level; + startPos++; + chNext = styler[startPos]; + styleNext = styler.StyleAt(startPos); + } + } break; + + case SCE_CANGJIE_TRIPLE_STRING_SQ: + case SCE_CANGJIE_TRIPLE_STRING_DQ: + case SCE_CANGJIE_RAWSTRING_SQ: + case SCE_CANGJIE_RAWSTRING_DQ: + if (style != stylePrev) { + levelNext++; + } + if (style != styleNext) { + levelNext--; + } + break; + + case SCE_CANGJIE_OPERATOR: + case SCE_CANGJIE_OPERATOR2: + if (ch == '{' || ch == '[' || ch == '(') { + levelNext++; + } else if (ch == '}' || ch == ']' || ch == ')') { + levelNext--; + } + break; + } + + if (visibleChars == 0 && !IsSpaceEquiv(style)) { + ++visibleChars; + } + if (startPos == lineStartNext) { + const FoldLineState foldNext(styler.GetLineState(lineCurrent + 1)); + levelNext = sci::max(levelNext, SC_FOLDLEVELBASE); + if (foldCurrent.lineComment) { + levelNext += foldNext.lineComment - foldPrev.lineComment; + } else if (foldCurrent.packageImport) { + levelNext += foldNext.packageImport - foldPrev.packageImport; + } else if (visibleChars) { + const Sci_PositionU bracePos = CheckBraceOnNextLine(styler, lineCurrent, SCE_CANGJIE_OPERATOR, SCE_CANGJIE_TASKMARKER); + if (bracePos) { + levelNext++; + startPos = bracePos + 1; // skip the brace + style = SCE_CANGJIE_OPERATOR; + chNext = styler[startPos]; + styleNext = styler.StyleAt(startPos); + } + } + + const int levelUse = levelCurrent; + int lev = levelUse | (levelNext << 16); + if (levelUse < levelNext) { + lev |= SC_FOLDLEVELHEADERFLAG; + } + styler.SetLevel(lineCurrent, lev); + + lineCurrent++; + lineStartNext = styler.LineStart(lineCurrent + 1); + lineStartNext = sci::min(lineStartNext, endPos); + levelCurrent = levelNext; + foldPrev = foldCurrent; + foldCurrent = foldNext; + visibleChars = 0; + } + } +} + +} + +LexerModule lmCangjie(SCLEX_CANGJIE, ColouriseCangjieDoc, "cj", FoldCangjieDoc); diff --git a/scintilla/lexers/LexSwift.cxx b/scintilla/lexers/LexSwift.cxx index 2b61ff553f..7989d1c87b 100644 --- a/scintilla/lexers/LexSwift.cxx +++ b/scintilla/lexers/LexSwift.cxx @@ -399,12 +399,8 @@ void ColouriseSwiftDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initS } } else if (IsNumberStartEx(sc.chPrev, sc.ch, sc.chNext)) { sc.SetState(SCE_SWIFT_NUMBER); - } else if ((sc.ch == '@' || sc.ch == '`') && IsIdentifierStartEx(sc.chNext)) { - chBefore = chPrevNonWhite; - if (chPrevNonWhite != '.') { - chBeforeIdentifier = chPrevNonWhite; - } - sc.SetState((sc.ch == '@') ? SCE_SWIFT_ATTRIBUTE : SCE_SWIFT_IDENTIFIER_BT); + } else if (sc.ch == '@' && IsIdentifierStartEx(sc.chNext)) { + sc.SetState(SCE_SWIFT_ATTRIBUTE); } else if (sc.ch == '$' && IsIdentifierCharEx(sc.chNext)) { sc.SetState(SCE_SWIFT_VARIABLE); } else if (sc.ch == '#') { @@ -425,12 +421,12 @@ void ColouriseSwiftDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initS } } } - } else if (IsIdentifierStartEx(sc.ch)) { + } else if (IsIdentifierStartEx(sc.ch) || (sc.ch == '`' && IsIdentifierStartEx(sc.chNext))) { chBefore = chPrevNonWhite; if (chPrevNonWhite != '.') { chBeforeIdentifier = chPrevNonWhite; } - sc.SetState(SCE_SWIFT_IDENTIFIER); + sc.SetState((sc.ch == '`') ? SCE_SWIFT_IDENTIFIER_BT : SCE_SWIFT_IDENTIFIER); } else if (sc.ch == '+' || sc.ch == '-') { if (sc.ch == sc.chNext) { // highlight ++ and -- as different style to simplify regex detection. diff --git a/scintilla/lexlib/LexerModule.cxx b/scintilla/lexlib/LexerModule.cxx index d1c4e91428..8e068e27b2 100644 --- a/scintilla/lexlib/LexerModule.cxx +++ b/scintilla/lexlib/LexerModule.cxx @@ -37,6 +37,7 @@ extern LexerModule lmAviSynth; extern LexerModule lmAwk; extern LexerModule lmBash; extern LexerModule lmBatch; +extern LexerModule lmCangjie; extern LexerModule lmCIL; extern LexerModule lmCMake; extern LexerModule lmCoffeeScript; @@ -121,6 +122,7 @@ const LexerModule * const lexerCatalogue[] = { &lmAwk, &lmBash, &lmBatch, + &lmCangjie, &lmCIL, &lmCMake, &lmCoffeeScript, diff --git a/src/EditAutoC.cpp b/src/EditAutoC.cpp index fe0d391db2..44a3ace823 100644 --- a/src/EditAutoC.cpp +++ b/src/EditAutoC.cpp @@ -671,6 +671,8 @@ enum { CSSKeywordIndex_PseudoElement = 3, CSharpKeywordIndex_Preprocessor = 3, CSharpKeywordIndex_CommentTag = 10, + CangjieKeywordIndex_Macro = 2, + CangjieKeywordIndex_Annotation = 3, DKeywordIndex_Preprocessor = 2, DKeywordIndex_Attribute = 3, DartKeywordIndex_Metadata = 4, @@ -1105,6 +1107,14 @@ static AddWordResult AutoC_AddSpecWord(WordList &pWList, int iCurrentStyle, int } break; + case NP2LEX_CANGJIE: + if (ch == '@' && iCurrentStyle == SCE_CANGJIE_DEFAULT) { + pWList.AddList(pLex->pKeyWords->pszKeyWords[CangjieKeywordIndex_Macro]); + pWList.AddList(pLex->pKeyWords->pszKeyWords[CangjieKeywordIndex_Annotation]); + return AddWordResult_IgnoreLexer; + } + break; + case NP2LEX_CSS: if (ch == '@' && iCurrentStyle == SCE_CSS_DEFAULT) { pWList.AddList(pLex->pKeyWords->pszKeyWords[CSSKeywordIndex_AtRule]); @@ -1378,7 +1388,7 @@ static AddWordResult AutoC_AddSpecWord(WordList &pWList, int iCurrentStyle, int break; case NP2LEX_SAS: - if (ch == '%') { + if (ch == '%' && iCurrentStyle == SCE_SAS_DEFAULT) { pWList.AddList(pLex->pKeyWords->pszKeyWords[SASKeywordIndex_Macro]); return AddWordResult_IgnoreLexer; } @@ -2460,6 +2470,7 @@ void EditToggleCommentLine(bool alternative) noexcept { case NP2LEX_ACTIONSCRIPT: case NP2LEX_ASYMPTOTE: case NP2LEX_BLOCKDIAG: + case NP2LEX_CANGJIE: case NP2LEX_CIL: case NP2LEX_CPP: case NP2LEX_CSHARP: @@ -2723,6 +2734,7 @@ void EditToggleCommentBlock(bool alternative) noexcept { case NP2LEX_ASYMPTOTE: case NP2LEX_AUTOHOTKEY: case NP2LEX_AVISYNTH: + case NP2LEX_CANGJIE: case NP2LEX_CIL: case NP2LEX_CPP: case NP2LEX_CSHARP: @@ -2991,6 +3003,17 @@ void InitAutoCompletionCache(LPCEDITLEXER pLex) noexcept { RawStringStyleMask[SCE_SH_STRING_SQ >> 5] |= (1U << (SCE_SH_STRING_SQ & 31)); break; + case NP2LEX_CANGJIE: + CharacterPrefixMask['r' >> 5] |= (1 << ('r' & 31)); + RawStringStyleMask[SCE_CANGJIE_RAWSTRING_SQ >> 5] |= (1U << (SCE_CANGJIE_RAWSTRING_SQ & 31)); + RawStringStyleMask[SCE_CANGJIE_RAWSTRING_DQ >> 5] |= (1U << (SCE_CANGJIE_RAWSTRING_DQ & 31)); + GenericTypeStyleMask[SCE_CANGJIE_CLASS >> 5] |= (1U << (SCE_CANGJIE_CLASS & 31)); + GenericTypeStyleMask[SCE_CANGJIE_INTERFACE >> 5] |= (1U << (SCE_CANGJIE_INTERFACE & 31)); + GenericTypeStyleMask[SCE_CANGJIE_STRUCT >> 5] |= (1U << (SCE_CANGJIE_STRUCT & 31)); + GenericTypeStyleMask[SCE_CANGJIE_ENUM >> 5] |= (1U << (SCE_CANGJIE_ENUM & 31)); + GenericTypeStyleMask[SCE_CANGJIE_WORD2 >> 5] |= (1U << (SCE_CANGJIE_WORD2 & 31)); + break; + case NP2LEX_CPP: CurrentWordCharSet[':' >> 5] |= (1 << (':' & 31)); CharacterPrefixMask['L' >> 5] |= (1 << ('L' & 31)); diff --git a/src/EditLexer.h b/src/EditLexer.h index 47a711878b..d20b93b4bd 100644 --- a/src/EditLexer.h +++ b/src/EditLexer.h @@ -205,7 +205,7 @@ using LPCEDITLEXER = const EDITLEXER *; #define NP2LEX_ZIG 63082 // SCLEX_ZIG Zig Source #define NP2LEX_OCAML 63083 // SCLEX_OCAML OCaml Source #define NP2LEX_HASKELL 63084 // SCLEX_HASKELL Haskell Source - +#define NP2LEX_CANGJIE 63085 // SCLEX_CANGJIE Cangjie Source #define NP2LEX_WINHEX 63086 // SCLEX_WINHEX WinHex Script #define NP2LEX_AVISYNTH 63087 // SCLEX_AVISYNTH AviSynth Script #define NP2LEX_TEKEXTHEX 63088 // SCLEX_TEKEXTHEX Tektronix extended HEX diff --git a/src/EditLexers/stlCangjie.cpp b/src/EditLexers/stlCangjie.cpp new file mode 100644 index 0000000000..ddaf54b0b5 --- /dev/null +++ b/src/EditLexers/stlCangjie.cpp @@ -0,0 +1,95 @@ +#include "EditLexer.h" +#include "EditStyleX.h" + +static KEYWORDLIST Keywords_Cangjie = {{ +//++Autogenerated -- start of section automatically generated +"abstract as break case catch class const continue do else enum extend false finally for foreign func " +"if import in init interface is let macro main match mut open operator override package private prop protected public " +"quote redef return spawn static struct super synchronized this throw true try type unsafe var where while " + +, // 1 types +"Bool Byte CPointer CString Float16 Float32 Float64 Int Int16 Int32 Int64 Int8 IntNative Nothing Rune This " +"UInt UInt16 UInt32 UInt64 UInt8 UIntNative Unit VArray " + +, // 2 macro +"C CallingConv FastNative Intrinsic When sourceFile( sourceLine( sourcePackage( " + +, // 3 annotation +"Annotation " + +, // 4 class +"ArrayIterator ArrayList Box BufferedInputStream BufferedOutputStream ByteArrayStream Directory Error Exception " +"File Future HashMap HashSet IOException Iterator LinkedList Object RangeIterator " +"StringBuilder StringReader StringWriter Thread ThreadLocal TreeMap " + +, // 5 struct +"Array CPointerHandle CPointerResource CStringResource DefaultHasher FileDescriptor FileInfo Path Range String " + +, // 6 interface +"Any CType Collection Comparable Countable Equal Equatable Hashable Hasher IOStream InputStream Iterable Map " +"OutputStream Resource Seekable Set ThreadContext ToString " + +, // 7 enumeration +"Endian OpenOption Option Ordering SeekPosition " + +, // 8 function +"alignOf( all( any( eprint( eprintln( ifNone( ifSome( init( main( print( println( refEq( sizeOf( zeroValue( " + +, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +//--Autogenerated -- end of section automatically generated +}}; + +static EDITSTYLE Styles_Cangjie[] = { + EDITSTYLE_DEFAULT, + { SCE_CANGJIE_WORD, NP2StyleX_Keyword, L"fore:#0000FF" }, + { SCE_CANGJIE_WORD2, NP2StyleX_TypeKeyword, L"fore:#0000FF" }, + { SCE_CANGJIE_MACRO, NP2StyleX_Macro, L"fore:#FF8000" }, + { SCE_CANGJIE_TYPE, NP2StyleX_Type, L"fore:#007F7F" }, + { SCE_CANGJIE_ANNOTATION, NP2StyleX_Annotation, L"fore:#FF8000" }, + { SCE_CANGJIE_CLASS, NP2StyleX_Class, L"fore:#0080FF" }, + { SCE_CANGJIE_STRUCT, NP2StyleX_Structure, L"fore:#0080FF" }, + { SCE_CANGJIE_INTERFACE, NP2StyleX_Interface, L"bold; fore:#1E90FF" }, + { SCE_CANGJIE_ENUM, NP2StyleX_Enumeration, L"fore:#FF8000" }, + { SCE_CANGJIE_FUNCTION_DEFINITION, NP2StyleX_FunctionDefinition, L"bold; fore:#A46000" }, + { SCE_CANGJIE_FUNCTION, NP2StyleX_Function, L"fore:#A46000" }, + { MULTI_STYLE(SCE_CANGJIE_COMMENTBLOCK, SCE_CANGJIE_COMMENTLINE, 0, 0), NP2StyleX_Comment, L"fore:#608060" }, + { MULTI_STYLE(SCE_CANGJIE_COMMENTBLOCKDOC, SCE_CANGJIE_COMMENTLINEDOC, 0, 0), NP2StyleX_DocComment, L"fore:#408040" }, + { SCE_CANGJIE_TASKMARKER, NP2StyleX_TaskMarker, L"bold; fore:#408080" }, + { MULTI_STYLE(SCE_CANGJIE_STRING_SQ, SCE_CANGJIE_STRING_DQ, SCE_CANGJIE_RUNE_SQ, SCE_CANGJIE_RUNE_DQ), NP2StyleX_String, L"fore:#008000" }, + { MULTI_STYLE(SCE_CANGJIE_TRIPLE_STRING_SQ, SCE_CANGJIE_TRIPLE_STRING_DQ, 0, 0), NP2StyleX_TripleQuotedString, L"fore:#F08000" }, + { MULTI_STYLE(SCE_CANGJIE_RAWSTRING_SQ, SCE_CANGJIE_RAWSTRING_DQ, 0, 0), NP2StyleX_RawString, L"fore:#F08000" }, + { SCE_CANGJIE_ESCAPECHAR, NP2StyleX_EscapeSequence, L"fore:#0080C0" }, + { SCE_CANGJIE_VARIABLE, NP2StyleX_Variable, L"fore:#9E4D2A" }, + { SCE_CANGJIE_NUMBER, NP2StyleX_Number, L"fore:#FF0000" }, + { MULTI_STYLE(SCE_CANGJIE_OPERATOR, SCE_CANGJIE_OPERATOR2, 0, 0), NP2StyleX_Operator, L"fore:#B000B0" }, +}; + +EDITLEXER lexCangjie = { + SCLEX_CANGJIE, NP2LEX_CANGJIE, +//Settings++Autogenerated -- start of section automatically generated + LexerAttr_AngleBracketGeneric | + LexerAttr_CharacterPrefix, + TAB_WIDTH_4, INDENT_WIDTH_4, + (1 << 0) | (1 << 1), // class, function + SCE_CANGJIE_FUNCTION_DEFINITION, + '\\', SCE_CANGJIE_ESCAPECHAR, 0, + 0, + SCE_CANGJIE_RUNE_SQ, 0, + SCE_CANGJIE_OPERATOR, SCE_CANGJIE_OPERATOR2 + , KeywordAttr32(0, KeywordAttr_PreSorted) // keywords + | KeywordAttr32(1, KeywordAttr_PreSorted) // types + | KeywordAttr32(2, KeywordAttr_NoLexer | KeywordAttr_NoAutoComp) // macro + | KeywordAttr32(3, KeywordAttr_PreSorted | KeywordAttr_NoAutoComp) // annotation + | KeywordAttr32(4, KeywordAttr_PreSorted) // class + | KeywordAttr32(5, KeywordAttr_PreSorted) // struct + | KeywordAttr32(6, KeywordAttr_PreSorted) // interface + | KeywordAttr64(7, KeywordAttr_PreSorted) // enumeration + | KeywordAttr64(8, KeywordAttr_NoLexer) // function + , SCE_CANGJIE_TASKMARKER, + SCE_CANGJIE_STRING_SQ, SCE_CANGJIE_ESCAPECHAR, +//Settings--Autogenerated -- end of section automatically generated + EDITLEXER_HOLE(L"Cangjie Source", Styles_Cangjie), + L"cj", + &Keywords_Cangjie, + Styles_Cangjie +}; diff --git a/src/Styles.cpp b/src/Styles.cpp index 4fac6eec83..9aabe798e8 100644 --- a/src/Styles.cpp +++ b/src/Styles.cpp @@ -73,6 +73,7 @@ extern EDITLEXER lexAwk; extern EDITLEXER lexBatch; extern EDITLEXER lexBlockdiag; +extern EDITLEXER lexCangjie; extern EDITLEXER lexCIL; extern EDITLEXER lexCMake; extern EDITLEXER lexCoffeeScript; @@ -186,6 +187,7 @@ static PEDITLEXER pLexArray[] = { &lexBatch, &lexBlockdiag, + &lexCangjie, &lexCIL, &lexCMake, &lexCoffeeScript, diff --git a/tools/KeywordCore.py b/tools/KeywordCore.py index 76e06e641e..c054c6779d 100644 --- a/tools/KeywordCore.py +++ b/tools/KeywordCore.py @@ -562,6 +562,45 @@ def parse_batch_api_file(path): ('command options', keywordMap['options'], KeywordAttr.NoLexer), ] +def parse_cangjie_api_file(path): + sections = read_api_file(path, '//') + keywordMap = { + 'function': ['main()', 'init()'] + } + for key, doc in sections: + if key in ('keywords', 'types'): + keywordMap[key] = doc.split() + elif key in ('macro', 'annotation'): + keywordMap[key] = re.findall(r'@(\w+\(?)', doc) + elif key == 'api': + keywordMap['class'] = re.findall(r'class\s+(\w+)', doc) + keywordMap['struct'] = re.findall(r'struct\s+(\w+)', doc) + keywordMap['interface'] = re.findall(r'interface\s+(\w+)', doc) + keywordMap['enumeration'] = re.findall(r'enum\s+(\w+)', doc) + items = re.findall(r'func\s+(\w+)', doc) + keywordMap['function'].extend(item + '()' for item in items) + + RemoveDuplicateKeyword(keywordMap, [ + 'keywords', + 'types', + 'class', + 'struct', + 'interface', + 'enumeration', + ]) + + return [ + ('keywords', keywordMap['keywords'], KeywordAttr.Default), + ('types', keywordMap['types'], KeywordAttr.Default), + ('macro', keywordMap['macro'], KeywordAttr.NoLexer | KeywordAttr.Special | KeywordAttr.NoAutoComp), + ('annotation', keywordMap['annotation'], KeywordAttr.Special | KeywordAttr.NoAutoComp), + ('class', keywordMap['class'], KeywordAttr.Default), + ('struct', keywordMap['struct'], KeywordAttr.Default), + ('interface', keywordMap['interface'], KeywordAttr.Default), + ('enumeration', keywordMap['enumeration'], KeywordAttr.Default), + ('function', keywordMap['function'], KeywordAttr.NoLexer), + ] + def parse_coffeescript_api_file(path): sections = read_api_file(path, '#') keywordMap = {} diff --git a/tools/KeywordUpdate.py b/tools/KeywordUpdate.py index eb0ea427ed..f605145ade 100644 --- a/tools/KeywordUpdate.py +++ b/tools/KeywordUpdate.py @@ -18,6 +18,7 @@ ('NP2LEX_BASH', 'stlBash.cpp', 'LexBash.cxx', ['Bash.sh', 'CShell.csh'], 0, parse_bash_api_file), ('NP2LEX_BATCH', 'stlBatch.cpp', 'LexBatch.cxx', 'Batch.bat', 0, parse_batch_api_file), + ('NP2LEX_CANGJIE', 'stlCangjie.cpp', 'LexCangjie.cxx', 'Cangjie.cj', 0, parse_cangjie_api_file), ('NP2LEX_CIL', 'stlCIL.cpp', 'LexCIL.cxx', '', 0, None), ('NP2LEX_CMAKE', 'stlCMake.cpp', 'LexCMake.cxx', 'CMake.cmake', 0, parse_cmake_api_file), ('NP2LEX_CONFIG', 'stlDefault.cpp', 'LexConfig.cxx', '', (0, 'Config'), None), diff --git a/tools/LexerConfig.py b/tools/LexerConfig.py index 14a82d54ba..556f4c786b 100644 --- a/tools/LexerConfig.py +++ b/tools/LexerConfig.py @@ -254,6 +254,20 @@ class KeywordAttr(IntFlag): 'string_style_range': ['SCE_GRAPHVIZ_STRING', 'SCE_GRAPHVIZ_ESCAPECHAR'], }, + 'NP2LEX_CANGJIE': { + 'cpp_style_comment': True, + 'comment_style_marker': 'SCE_CANGJIE_TASKMARKER', + 'default_fold_level': ['class', 'function'], + 'default_fold_ignore_inner': 'SCE_CANGJIE_FUNCTION_DEFINITION', + 'escape_char_style': 'SCE_CANGJIE_ESCAPECHAR', + 'raw_string_style': ['SCE_CANGJIE_RAWSTRING_SQ', 'SCE_CANGJIE_RAWSTRING_DQ'], + 'character_style': ['SCE_CANGJIE_RUNE_SQ', 'SCE_CANGJIE_RUNE_DQ'], + 'character_prefix': ['r'], + 'angle_bracket_generic': True, + 'generic_type_style': ['SCE_CANGJIE_CLASS', 'SCE_CANGJIE_INTERFACE', 'SCE_CANGJIE_STRUCT', 'SCE_CANGJIE_ENUM', 'SCE_CANGJIE_WORD2'], + 'operator_style': ['SCE_CANGJIE_OPERATOR', 'SCE_CANGJIE_OPERATOR2'], + 'string_style_range': ['SCE_CANGJIE_STRING_SQ', 'SCE_CANGJIE_ESCAPECHAR'], + }, 'NP2LEX_CIL': { 'cpp_style_comment': True, 'comment_style_marker': 'SCE_CIL_COMMENTBLOCK', diff --git a/tools/lang/Cangjie.cj b/tools/lang/Cangjie.cj new file mode 100644 index 0000000000..d727744e37 --- /dev/null +++ b/tools/lang/Cangjie.cj @@ -0,0 +1,140 @@ +// 2024-06-21 https://developer.huawei.com/consumer/cn/cangjie + +//! keywords =========================================================== +// https://developer.huawei.com/consumer/cn/doc/openharmony-cangjie/keyword +abstract as +break +case catch class const continue +do +else enum extend +false finally for foreign func +if import in init interface is +let +macro main match mut +open operator override +package private prop protected public +quote +redef return +spawn static struct super synchronized +this throw true try type +unsafe +var +where while + +//! types =========================================================== +Nothing This VArray +// std.core types +Byte Int UInt +Int8 Int16 Int32 Int64 IntNative +UInt8 UInt16 UInt32 UInt64 UIntNative +Float16 Float32 Float64 +Bool Rune Unit +CPointer CString + +//! macro =========================================================== +@sourcePackage() +@sourceFile() +@sourceLine() +@Intrinsic +@FastNative +@When + +@C +@CallingConv + +//! annotation =========================================================== +@Annotation + +//! api =========================================================== +package std.core { + func alignOf(): UIntNative where T <: CType + func eprint(str: String, flush!: Bool = true): Unit + func eprintln(str: String): Unit + func ifNone(o: Option, action: () -> Unit): Unit + func ifSome(o: Option, action: (T) -> Unit): Unit + func print(arg: T, flush!: Bool = false): Unit where T <: ToString + func println(arg: T): Unit where T <: ToString + func refEq(a: Object, b: Object): Bool + func sizeOf(): UIntNative where T <: CType + func zeroValue(): T + + interface Any + interface CType + interface Collection <: Iterable + interface Comparable <: Equatable & Less & Greater & LessOrEqual & GreaterOrEqual + interface Countable + interface Equal + interface Equatable + interface Hashable + interface Hasher + interface Iterable + interface Resource + interface ThreadContext + interface ToString + + class ArrayIterator <: Iterator + class Box + class Future + abstract class Iterator <: Iterable + open class Object <: Any + class RangeIterator <: Iterator where T <: Countable & Comparable & Equatable + class StringBuilder <: ToString + class Thread + class ThreadLocal + + enum Endian + enum Option + enum Ordering + + struct Array + struct CPointerHandle where T <: CType + struct CPointerResource <: Resource where T <: CType + struct CStringResource <: Resource + struct DefaultHasher <: Hasher + struct Range <: Iterable where T <: Countable & Comparable & Equatable + struct String <: Collection & Equatable & Comparable & Hashable & ToString + + open class Error <: ToString + open class Exception <: ToString +} + +package std.collection { + func all(predicate: (T) -> Bool): (Iterable) -> Bool + func any(predicate: (T) -> Bool): (Iterable) -> Bool + + interface Map <: Collection<(K, V)> where K <: Equatable + interface Set <: Collection where T <: Equatable + + class ArrayList <: Collection + class HashMap <: Map where K <: Hashable & Equatable + class HashSet <: Set where T <: Hashable & Equatable + class LinkedList <: Collection + class TreeMap <: Map where K <: Comparable +} + +package std.fs { + class Directory <: Iterable + class File <: Resource & IOStream & Seekable + + enum OpenOption + + struct FileDescriptor + struct FileInfo <: Equatable + struct Path <: Equatable & Hashable & ToString +} + +package std.io { + interface IOStream <: InputStream & OutputStream + interface InputStream + interface OutputStream + interface Seekable + + class BufferedInputStream <: InputStream where T <: InputStream + class BufferedOutputStream <: OutputStream where T <: OutputStream + class ByteArrayStream <: IOStream & Seekable + class StringReader where T <: InputStream + class StringWriter where T <: OutputStream + + enum SeekPosition + class IOException <: Exception +} diff --git a/tools/lang/SAS.sas b/tools/lang/SAS.sas index 8527bdea68..60854a7a11 100644 --- a/tools/lang/SAS.sas +++ b/tools/lang/SAS.sas @@ -2,7 +2,7 @@ /* SAS Viya 2024.06 https://go.documentation.sas.com/doc/en/pgmsascdc/v_052/pgmsaswlcm/home.htm */ /* SAS 9.4 / Viya 3.5 https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/pgmsashome/home.htm */ -/*! keywords =============================================================== */ +/*! keywords ======================================================== */ /* Operators */ /* https://go.documentation.sas.com/doc/en/pgmsascdc/v_052/lepg/titlepage.htm */ eq ne gt lt ge le in @@ -110,7 +110,7 @@ update where validate where -/*! macro ================================================================== */ +/*! macro ======================================================== */ /* Macro Language */ /* https://go.documentation.sas.com/doc/en/pgmsascdc/v_052/mcrolref/titlepage.htm */ %include @@ -189,7 +189,7 @@ where %ds2csv(argument-1=value-1, argument-2=value-2 <,argument-3=value-3 ...>) %tslit(literal text) -/*! functions ============================================================== */ +/*! functions ======================================================== */ /* Functions and CALL Routines */ /* https://go.documentation.sas.com/doc/en/pgmsascdc/v_052/lefunctionsref/titlepage.htm */ abs()