├── testData
├── ide
│ ├── formatter
│ │ ├── ifElse.rho
│ │ ├── parens.rho
│ │ ├── mapMethods.rho
│ │ ├── ifElseFormatted.rho
│ │ ├── parensFormatted.rho
│ │ ├── URI.rho
│ │ ├── URIFormatted.rho
│ │ ├── mapMethodsFormatted.rho
│ │ ├── complex.rho
│ │ └── complexFormatted.rho
│ └── folding
│ │ └── procedure.rho
├── parser
│ ├── token.rho
│ └── token.txt
└── lexer
│ ├── token.rho
│ └── token.txt
├── docs
├── settings-page.png
└── beta-0.1.0.svg
├── src
├── coop
│ └── rchain
│ │ └── lang
│ │ ├── formatter
│ │ ├── RholangWrappingProcessor.kt
│ │ ├── RholangBlockContext.kt
│ │ ├── settings
│ │ │ └── RholangCodeStyleSettingsProvider.kt
│ │ ├── RholangFormattingModelBuilder.kt
│ │ ├── RholangSpaceProcessor.kt
│ │ ├── RholangIndentProcessor.kt
│ │ └── RholangBlock.kt
│ │ ├── icons
│ │ └── rholang-red-16.png
│ │ ├── RhoIcons.kt
│ │ ├── RhoLanguage.kt
│ │ ├── psi
│ │ ├── RhoFile.kt
│ │ └── RhoElements.kt
│ │ ├── RhoCommenter.kt
│ │ ├── RhoFileType.kt
│ │ ├── util
│ │ └── PsiTreeHelpUtil.kt
│ │ ├── RhoHighlightingAnnotator.kt
│ │ ├── RhoColors.kt
│ │ ├── folding
│ │ └── RholangFoldingBuilder.kt
│ │ ├── RhoParserDefinition.kt
│ │ ├── RhoColorSettingsPage.kt
│ │ ├── Rho.flex
│ │ ├── RhoSyntaxHighlighter.kt
│ │ └── Rho.bnf
├── rholang.cf
└── rholang-mercury.cf
├── .idea
├── codeStyles
│ ├── codeStyleConfig.xml
│ └── Project.xml
├── vcs.xml
├── modules.xml
├── misc.xml
├── codeStyleSettings.xml
└── rholang-idea.iml
├── test
└── coop
│ └── rchain
│ ├── RholangTestUtil.kt
│ ├── lang
│ ├── parser
│ │ └── RholangParserTest.kt
│ └── lexer
│ │ └── RholangLexTest.kt
│ └── ide
│ └── folding
│ └── RholangCodeInsightTest.kt
├── .editorconfig
├── CONTRIBUTING.md
├── LICENSE
├── .gitignore
├── resources
└── META-INF
│ └── plugin.xml
└── README.md
/testData/ide/formatter/ifElse.rho:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/testData/ide/formatter/parens.rho:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/testData/ide/formatter/mapMethods.rho:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/testData/ide/formatter/ifElseFormatted.rho:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/testData/ide/formatter/parensFormatted.rho:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/settings-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tgrospic/rholang-idea/HEAD/docs/settings-page.png
--------------------------------------------------------------------------------
/src/coop/rchain/lang/formatter/RholangWrappingProcessor.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.formatter
2 |
3 | class RholangWrappingProcessor
4 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/icons/rholang-red-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tgrospic/rholang-idea/HEAD/src/coop/rchain/lang/icons/rholang-red-16.png
--------------------------------------------------------------------------------
/testData/ide/formatter/URI.rho:
--------------------------------------------------------------------------------
1 | new ack, stdout(`rho:io:stdout`), stdoutAck(`rho:io:stdoutAck`) in { stdoutAck!("hello, world!", *ack) | for (_ <- ack) { stdout!("received") } }
2 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/testData/ide/folding/procedure.rho:
--------------------------------------------------------------------------------
1 | new time_contract in {
2 | contract time_contract(stream) = {
3 | log-time(stream)
4 | } |
5 | time_contract!(ostream-new("test.txt")) |
6 | time_contract!(ostream-new("test2.txt"))
7 | }
8 |
--------------------------------------------------------------------------------
/test/coop/rchain/RholangTestUtil.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain
2 |
3 | import java.io.File
4 |
5 | object RholangTestUtil {
6 | val testDataPath = File("testData").absolutePath
7 | val baseTestDataPath: String
8 | get() = testDataPath
9 | }
10 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/RhoIcons.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang
2 |
3 | import com.intellij.openapi.util.IconLoader
4 |
5 | object RhoIcons {
6 | val RED_EDITION = IconLoader.getIcon("/coop/rchain/lang/icons/rholang-red-16.png")
7 |
8 | val DEFAULT = RED_EDITION
9 | }
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.{md}]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/testData/ide/formatter/URIFormatted.rho:
--------------------------------------------------------------------------------
1 | // A simple Hello World contract
2 | new helloworld in {
3 | contract helloworld( world ) = {
4 | for( msg <- world ) {
5 | print(msg)
6 | }
7 | } |
8 | new world in {
9 | helloworld!(world) |
10 | world!("Hello World")
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/RhoLanguage.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang
2 |
3 | import com.intellij.lang.Language
4 |
5 | class RhoLanguage private constructor() : Language("Rholang") {
6 | override fun isCaseSensitive() = true
7 |
8 | override fun getDisplayName() = "Rholang"
9 |
10 | companion object {
11 | val INSTANCE = RhoLanguage()
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/testData/parser/token.rho:
--------------------------------------------------------------------------------
1 | new testResult, philosopher1, philosopher2 in {
2 | new north, south, knife, spoon in {
3 | north!(*knife) |
4 | south!(*spoon) |
5 | for (@knf <- north; @spn <- south) {
6 | philosopher1!(true) |
7 | north!(knf) |
8 | south!(spn)
9 | } |
10 | for (@spn <- south; @knf <- north) {
11 | philosopher2!(true) |
12 | north!(knf) |
13 | south!(spn)
14 | }
15 | } |
16 | for(_ <- philosopher1; _ <- philosopher2) {
17 | testResult!(true)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/coop/rchain/lang/parser/RholangParserTest.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.parser
2 |
3 | import com.intellij.testFramework.ParsingTestCase
4 | import coop.rchain.RholangTestUtil
5 | import coop.rchain.lang.RhoParserDefinition
6 | import java.nio.file.Paths
7 |
8 | class RholangParserTest : ParsingTestCase("", "rho", RhoParserDefinition()) {
9 |
10 | override fun getTestDataPath(): String {
11 | return Paths.get(RholangTestUtil.baseTestDataPath, "parser").toString()
12 | }
13 |
14 | fun testtoken() {
15 | doTest(true)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/formatter/RholangBlockContext.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.formatter
2 |
3 | import com.intellij.formatting.FormattingMode
4 | import com.intellij.psi.codeStyle.CodeStyleSettings
5 | import com.intellij.psi.codeStyle.CommonCodeStyleSettings
6 | import coop.rchain.lang.RhoLanguage
7 |
8 | class RholangBlockContext(val settings: CodeStyleSettings, val mode: FormattingMode) {
9 | val rholangSettings: CommonCodeStyleSettings
10 |
11 | init {
12 | rholangSettings = settings.getCommonSettings(RhoLanguage.INSTANCE)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.idea/codeStyleSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/psi/RhoFile.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.psi
2 |
3 | import com.intellij.extapi.psi.PsiFileBase
4 | import com.intellij.openapi.fileTypes.FileType
5 | import com.intellij.psi.FileViewProvider
6 | import coop.rchain.lang.RhoFileType
7 | import coop.rchain.lang.RhoLanguage
8 |
9 | import javax.swing.*
10 |
11 | class RhoFile(viewProvider: FileViewProvider) : PsiFileBase(viewProvider, RhoLanguage.Companion.INSTANCE) {
12 |
13 | override fun getFileType(): FileType {
14 | return RhoFileType.Companion.INSTANCE
15 | }
16 |
17 | override fun toString(): String {
18 | return "Rholang File"
19 | }
20 |
21 | override fun getIcon(flags: Int): Icon? {
22 | return super.getIcon(flags)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test/coop/rchain/lang/lexer/RholangLexTest.kt:
--------------------------------------------------------------------------------
1 | //package coop.rchain.lang.lexer
2 | //
3 | //import com.intellij.lexer.Lexer
4 | //import com.intellij.testFramework.LexerTestCase
5 | //import coop.rchain.RholangTestUtil
6 | //import coop.rchain.lang.RhoLexerAdapter
7 | //
8 | //import java.nio.file.Paths
9 | //
10 | //class RholangLexTest : LexerTestCase() {
11 | //
12 | // override fun createLexer(): Lexer {
13 | // return RhoLexerAdapter()
14 | // }
15 | //
16 | // override fun getDirPath(): String =
17 | // Paths.get(RholangTestUtil.baseTestDataPath, "lexer").toString()
18 | //
19 | // override fun getPathToTestDataFile(extension: String): String =
20 | // this.getDirPath() + "/" + this.getTestName(true) + extension
21 | //
22 | // fun testToken() {
23 | // doFileTest("rho")
24 | // }
25 | //}
26 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Any suggestions, bugs, testing, pull-requests, issues are very welcome.
4 |
5 | ## Development setup
6 |
7 | More info on [README##development](./README.md##development) page section.
8 |
9 | ## TODO
10 |
11 | - write more tests and configure CI
12 | - write [Completion Contributor][idea-completion]
13 | - write [Reference Contributor][idea-reference]
14 | - add [plugin actions][idea-plugin-actions]
15 | - connect with the compiler (get semantic info)
16 | - ...
17 |
18 | [idea-completion]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/completion_contributor.html
19 | [idea-reference]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/reference_contributor.html
20 | [idea-plugin-actions]: https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html
21 |
--------------------------------------------------------------------------------
/docs/beta-0.1.0.svg:
--------------------------------------------------------------------------------
1 |
21 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/RhoCommenter.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang
2 |
3 | import com.intellij.lang.Commenter
4 | import com.intellij.psi.tree.IElementType
5 | import coop.rchain.lang.psi.RhoTypes
6 |
7 | class RhoCommenter : Commenter {
8 | override fun getLineCommentPrefix(): String? {
9 | return "//"
10 | }
11 |
12 | override fun getBlockCommentPrefix(): String? {
13 | return "/*"
14 | }
15 |
16 | override fun getBlockCommentSuffix(): String? {
17 | return "*/"
18 | }
19 |
20 | override fun getCommentedBlockCommentPrefix(): String? {
21 | return null
22 | }
23 |
24 | override fun getCommentedBlockCommentSuffix(): String? {
25 | return null
26 | }
27 |
28 | val lineCommentTokenType: IElementType?
29 | get() = RhoTypes.LINE_COMMENT
30 |
31 | val blockCommentTokenType: IElementType?
32 | get() = RhoTypes.BLOCK_COMMENT
33 | }
34 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/psi/RhoElements.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.psi
2 |
3 | import com.intellij.extapi.psi.ASTWrapperPsiElement
4 | import com.intellij.lang.ASTNode
5 | import com.intellij.psi.PsiElement
6 | import com.intellij.psi.tree.IElementType
7 | import coop.rchain.lang.RhoLanguage
8 | import org.jetbrains.annotations.NonNls
9 |
10 | class RhoElementType(@NonNls debugName: String) : IElementType(debugName, RhoLanguage.INSTANCE)
11 |
12 | class RhoTokenType(@NonNls debugName: String) : IElementType(debugName, RhoLanguage.INSTANCE)
13 |
14 | // Named element
15 | interface RhoNamedElement : RhoCompositeElement
16 |
17 | abstract class RhoNamedElementImpl(node: ASTNode) : RhoCompositeElementImpl(node), RhoNamedElement
18 |
19 | interface RhoCompositeElement : PsiElement
20 |
21 | abstract class RhoCompositeElementImpl(node: ASTNode) : ASTWrapperPsiElement(node), RhoCompositeElement
22 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/RhoFileType.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang
2 |
3 | import com.intellij.openapi.fileTypes.FileTypeConsumer
4 | import com.intellij.openapi.fileTypes.FileTypeFactory
5 | import com.intellij.openapi.fileTypes.LanguageFileType
6 |
7 | import javax.swing.*
8 |
9 | class RhoFileTypeFactory : FileTypeFactory() {
10 | override fun createFileTypes(fileTypeConsumer: FileTypeConsumer) {
11 | fileTypeConsumer.consume(RhoFileType.INSTANCE, "rho")
12 | }
13 | }
14 |
15 | class RhoFileType private constructor() : LanguageFileType(RhoLanguage.INSTANCE) {
16 |
17 | override fun getName(): String {
18 | return "Rholang file"
19 | }
20 |
21 | override fun getDescription(): String {
22 | return name
23 | }
24 |
25 | override fun getDefaultExtension(): String {
26 | return "rho"
27 | }
28 |
29 | override fun getIcon(): Icon? {
30 | return RhoIcons.DEFAULT
31 | }
32 |
33 | companion object {
34 | val INSTANCE = RhoFileType()
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/formatter/settings/RholangCodeStyleSettingsProvider.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.formatter.settings
2 |
3 | import com.intellij.lang.Language
4 | import com.intellij.psi.codeStyle.CommonCodeStyleSettings
5 | import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider
6 | import coop.rchain.lang.RhoLanguage
7 |
8 | class RholangCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvider() {
9 | override fun getLanguage(): Language {
10 | return RhoLanguage.INSTANCE
11 | }
12 |
13 | override fun getCodeSample(settingsType: LanguageCodeStyleSettingsProvider.SettingsType): String? {
14 | return null
15 | }
16 |
17 | override fun getDefaultCommonSettings(): CommonCodeStyleSettings? {
18 | val defaultSettings = CommonCodeStyleSettings(language)
19 | val indentOptions = defaultSettings.initIndentOptions()
20 | indentOptions.INDENT_SIZE = 2
21 | indentOptions.CONTINUATION_INDENT_SIZE = 2
22 | return defaultSettings
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/.idea/rholang-idea.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/testData/ide/formatter/mapMethodsFormatted.rho:
--------------------------------------------------------------------------------
1 | // all methods modifying the underlying collection return new Map
2 | // prints 1
3 | new stdout in { stdout!({"one" : 2, "two" : 2, "three" : 3}.get("one")) |
4 | // if element is not present in the map will return Nil -- prints Nil
5 | stdout!({
6 | "one" : 1, "two" : 2, "three" : 3}.get("four")) |
7 | // prints false
8 | stdout!({"one" : 1, "two" : 2, "three" : 3}.contains("four")) |
9 | // prints true
10 | stdout!({"one" : 1, "two" : 2, "three" : 3}.contains("three")) |
11 | // prints @{{"three" : 3, "two" : 2}}
12 | stdout!({"one" : 1, "two" : 2, "three" : 3}.delete("one")) |
13 | // doesn't change the collection, prints @{{"one" : 1, "three" : 3, "two" : 2}}
14 | stdout!({"one" : 1, "two" : 2, "three" : 3}.delete("four")) |
15 | // returns new map which is a result of subtracting elements of second map from the base map
16 | stdout!({"one" : 1, "two" : 2, "three" : 3}.diff({"one" : 1, "four": 4})) |
17 | // merges two maps -- returns @{{"four" : 4, "one" : 1, "three" : 3, "two" : 2}}
18 | stdout!({"one" : 1, "two" : 2, "three" : 3}.union({"one" : 1, "four": 4}))
19 | }
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017-present RChain.coop (Tomislav Grospic)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/testData/ide/formatter/complex.rho:
--------------------------------------------------------------------------------
1 | new testResult, updateTestResult in { testResult!(true) | contract updateTestResult(@bool, return) = { for(@r <- testResult) { match [r, bool] { [true, true] => { testResult!(true) | return!(true) } _ => { testResult!(false) | return!(false) } } } } | contract @"CoatCheckDemo"(_) = { new MakeCoatCheck in { contract MakeCoatCheck(ret) = { new port, table in { ret!(*port) | for(@"new", @arg, ack <= port) { new ticket in { ack!(*ticket) | @{*ticket | *table}!(arg) } } | for(@"get", @arg, ack <= port) { for (@value <- @{arg | *table}) { @{arg | *table}!(value) | ack!(value) } } | for(@"set", @arg1, @arg2, ack <= port) { for (_ <- @{arg1 | *table}) { @{arg1 | *table}!(arg2) | ack!(true) } } } } |
2 | // Usage
3 | new ret, get, set in { MakeCoatCheck!(*ret) | for (cc <- ret) {
4 | // Creates new cell with initial value 0
5 | cc!("new", 0, *ret) | for (ticket <- ret) { contract get(return) = { cc!("get", *ticket, *return) } | contract set(@value, return) = { cc!("set", *ticket, value, *return) } | get!(*ret) | for(@r <- ret) { updateTestResult!(r == 0, *ret) | for(_ <- ret){ set!(1, *ret) | for(_ <- ret) { get!(*ret) | for(@r <- ret) { updateTestResult!(r == 1, *ret) } } } } } } } } } | @"CoatCheckDemo"!(Nil) }
6 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/util/PsiTreeHelpUtil.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.util
2 |
3 | import com.intellij.lang.ASTNode
4 | import com.intellij.psi.PsiComment
5 | import com.intellij.psi.PsiElement
6 | import com.intellij.psi.PsiWhiteSpace
7 | import com.intellij.psi.util.PsiTreeUtil
8 |
9 | object PsiTreeHelpUtil {
10 |
11 | fun getPrevSiblingSkipWhiteSpacesAndComments(sibling: ASTNode?): ASTNode? {
12 | if (sibling == null) return null
13 | var treePrev: ASTNode? = sibling.treePrev
14 | while (treePrev != null && isWhitespaceOrComment(treePrev.psi)) {
15 | treePrev = treePrev.treePrev
16 | }
17 | return treePrev
18 | }
19 |
20 | /**
21 | * The difference of this method from getPrevSiblingSkipWhiteSpacesAndComments is that this one obtain the previous leaf node rather than sibling.
22 | * @param current
23 | * @return
24 | */
25 | fun getPrevLeafSkipWhiteSpacesAndComments(current: ASTNode?): PsiElement? {
26 | if (current == null) return null
27 | var treePrev = PsiTreeUtil.prevLeaf(current.psi)
28 | while (treePrev != null && isWhitespaceOrComment(treePrev)) {
29 | treePrev = PsiTreeUtil.prevLeaf(treePrev)
30 | }
31 | return treePrev
32 | }
33 |
34 | private fun isWhitespaceOrComment(psi: PsiElement): Boolean {
35 | return psi is PsiWhiteSpace || psi is PsiComment
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
2 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
3 |
4 | # User-specific stuff:
5 | .idea/**/workspace.xml
6 | .idea/**/tasks.xml
7 | .idea/dictionaries
8 |
9 | # Sensitive or high-churn files:
10 | .idea/**/dataSources/
11 | .idea/**/dataSources.ids
12 | .idea/**/dataSources.local.xml
13 | .idea/**/sqlDataSources.xml
14 | .idea/**/dynamic.xml
15 | .idea/**/uiDesigner.xml
16 |
17 | # Gradle:
18 | .idea/**/gradle.xml
19 | .idea/**/libraries
20 |
21 | # CMake
22 | cmake-build-debug/
23 | cmake-build-release/
24 |
25 | # Mongo Explorer plugin:
26 | .idea/**/mongoSettings.xml
27 |
28 | ## File-based project format:
29 | *.iws
30 |
31 | ## Plugin-specific files:
32 |
33 | # IntelliJ
34 | out/
35 |
36 | # mpeltonen/sbt-idea plugin
37 | .idea_modules/
38 |
39 | # JIRA plugin
40 | atlassian-ide-plugin.xml
41 |
42 | # Cursive Clojure plugin
43 | .idea/replstate.xml
44 |
45 | # Crashlytics plugin (for Android Studio and IntelliJ)
46 | com_crashlytics_export_strings.xml
47 | crashlytics.properties
48 | crashlytics-build.properties
49 | fabric.properties
50 |
51 | # Generated code from parser and lexer
52 | gen/
53 |
54 | # Generated plugin
55 | .idea/rholang-idea.jar
56 | .idea/rholang-idea.zip
57 |
58 | *.java~
59 | /*.jar
60 |
61 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/RhoHighlightingAnnotator.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang
2 |
3 | import com.intellij.lang.annotation.AnnotationHolder
4 | import com.intellij.lang.annotation.Annotator
5 | import com.intellij.psi.PsiElement
6 | import coop.rchain.lang.psi.*
7 |
8 | class RhoHighlightingAnnotator : Annotator {
9 |
10 | override fun annotate(element: PsiElement, holder: AnnotationHolder) {
11 | val (partToHighlight, color) = highlightElement(element) ?: return
12 |
13 | holder.createInfoAnnotation(partToHighlight, null).textAttributes = color.textAttributesKey
14 | }
15 |
16 | private fun highlightElement(element: PsiElement): Pair? = when (element) {
17 | is RhoNamedElement -> {
18 | val color = colorFor(element)
19 | val part = partToHighlight(element)
20 | if (color != null && part != null)
21 | part to color else null
22 | }
23 | else -> null
24 | }
25 | }
26 |
27 | private fun colorFor(element: RhoCompositeElement): RhoColor? = when (element) {
28 | // is RhoContractName -> RhoColor.FUNCTION
29 | // is RhoConstrName -> RhoColor.CONSTRUCTOR
30 | // is RhoChan -> RhoColor.PARAMETER
31 | // is RhoTypeTerm -> RhoColor.TYPE_PARAMETER
32 | is RhoNameVar-> RhoColor.RHO_NAME
33 | // is RhoFnName -> RhoColor.FUNCTION
34 | // is RhoCPattern_ -> RhoColor.BIND_PARAMETER
35 | // is RhoChanRefSymbol -> RhoColor.KEYWORD
36 | else -> null
37 | }
38 |
39 | private fun partToHighlight(element: RhoNamedElement): PsiElement? = when (element) {
40 | is RhoNamedElement -> element
41 | else -> null
42 | }
43 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/formatter/RholangFormattingModelBuilder.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.formatter
2 |
3 | import com.intellij.formatting.FormatTextRanges
4 | import com.intellij.formatting.FormattingMode
5 | import com.intellij.formatting.FormattingModel
6 | import com.intellij.formatting.FormattingModelBuilderEx
7 | import com.intellij.lang.ASTNode
8 | import com.intellij.openapi.util.TextRange
9 | import com.intellij.psi.PsiElement
10 | import com.intellij.psi.PsiFile
11 | import com.intellij.psi.codeStyle.CodeStyleSettings
12 | import com.intellij.psi.codeStyle.CommonCodeStyleSettings
13 | import com.intellij.psi.formatter.DocumentBasedFormattingModel
14 |
15 | class RholangFormattingModelBuilder : FormattingModelBuilderEx {
16 | override fun createModel(element: PsiElement, settings: CodeStyleSettings, mode: FormattingMode): FormattingModel {
17 | val psiFile = element.containingFile
18 | val rootNode = psiFile.node
19 | val context = RholangBlockContext(settings, mode)
20 | val rootBlock = RholangBlock(rootNode, null, null, settings, context)
21 | return DocumentBasedFormattingModel(rootBlock, element.project, settings, psiFile.fileType, psiFile)
22 | }
23 |
24 | override fun getIndentOptionsToUse(file: PsiFile, ranges: FormatTextRanges, settings: CodeStyleSettings): CommonCodeStyleSettings.IndentOptions? {
25 | return null
26 | }
27 |
28 | override fun createModel(element: PsiElement, settings: CodeStyleSettings): FormattingModel {
29 | return createModel(element, settings, FormattingMode.REFORMAT)
30 | }
31 |
32 | override fun getRangeAffectingIndent(file: PsiFile, offset: Int, elementAtOffset: ASTNode): TextRange? {
33 | return null
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/test/coop/rchain/ide/folding/RholangCodeInsightTest.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.ide.folding
2 |
3 | import com.intellij.openapi.command.WriteCommandAction
4 | import com.intellij.openapi.util.TextRange
5 | import com.intellij.psi.codeStyle.CodeStyleManager
6 | import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
7 | import com.intellij.util.containers.ContainerUtil
8 | import coop.rchain.RholangTestUtil
9 |
10 |
11 | class RholangCodeInsightTest : LightCodeInsightFixtureTestCase() {
12 | override fun getTestDataPath(): String {
13 | return RholangTestUtil.baseTestDataPath
14 | }
15 |
16 | fun testFolding() {
17 | doTestFolding("blockDocComment")
18 | doTestFolding("procedure")
19 | }
20 |
21 | fun testFormatter() {
22 | object : WriteCommandAction.Simple(project) {
23 | @Throws(Throwable::class)
24 | override fun run() {
25 | myFixture.configureByFiles("./ide/formatter/token.rho")
26 | CodeStyleManager.getInstance(project).reformatText(myFixture.file,
27 | ContainerUtil.newArrayList(myFixture.file.textRange))
28 | }
29 | }.execute()
30 | myFixture.checkResultByFile("./ide/formatter/tokenFormatted.rho")
31 | }
32 |
33 | fun testFormatter2() {
34 | object : WriteCommandAction.Simple(project) {
35 | @Throws(Throwable::class)
36 | override fun run() {
37 | myFixture.configureByFiles("./ide/formatter/simpleOne.rho")
38 | CodeStyleManager.getInstance(project).reformatText(myFixture.file,
39 | ContainerUtil.newArrayList(myFixture.file.textRange))
40 | }
41 | }.execute()
42 | myFixture.checkResultByFile("./ide/formatter/simpleOneFormatted.rho")
43 | }
44 |
45 | private fun doTestFolding(testName: String) {
46 | myFixture.testFolding("$testDataPath/ide/folding/$testName.rho")
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/RhoColors.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang
2 |
3 | import com.intellij.openapi.editor.colors.TextAttributesKey
4 | import com.intellij.openapi.options.colors.AttributesDescriptor
5 | import com.intellij.openapi.editor.DefaultLanguageHighlighterColors as DefaultColor
6 | import com.intellij.ide.highlighter.JavaHighlightingColors
7 | import com.intellij.openapi.editor.HighlighterColors
8 |
9 | /**
10 | * See [RhoColorSettingsPage] and [RhoSyntaxHighlighter]
11 | */
12 | enum class RhoColor(humanName: String, default: TextAttributesKey) {
13 | FUNCTION("Function declaration",DefaultColor.FUNCTION_DECLARATION),
14 | CONSTRUCTOR("Constructor", DefaultColor.FUNCTION_CALL),
15 | TYPE_PARAMETER("Type parameter", JavaHighlightingColors.TYPE_PARAMETER_NAME_ATTRIBUTES),
16 | BIND_PARAMETER("Bind parameter", JavaHighlightingColors.LOCAL_VARIABLE_ATTRIBUTES),
17 | PARAMETER("Parameter", JavaHighlightingColors.INSTANCE_FIELD_ATTRIBUTES),
18 |
19 | KEYWORD("Keyword", DefaultColor.KEYWORD),
20 | IDENTIFIER("Identifier", DefaultColor.IDENTIFIER),
21 | BLOCK_COMMENT("Comment block", DefaultColor.BLOCK_COMMENT),
22 | LINE_COMMENT("Comment line", DefaultColor.LINE_COMMENT),
23 | DOC_COMMENT("Comment documentation", DefaultColor.DOC_COMMENT),
24 | STRING("String", DefaultColor.STRING),
25 | NUMBER("Number", DefaultColor.NUMBER),
26 | BRACKETS("Brackets", DefaultColor.BRACKETS),
27 | BRACES("Braces", DefaultColor.BRACES),
28 | PARENTHESIS("Parenthesis", DefaultColor.PARENTHESES),
29 | COMMA("Comma", DefaultColor.COMMA),
30 | SEMICOLON("Semicolon", DefaultColor.SEMICOLON),
31 | OPERATORS("Operators", DefaultColor.OPERATION_SIGN),
32 | BAD_CHAR("Bad character", HighlighterColors.BAD_CHARACTER),
33 | RHO_NAME("RhoName", DefaultColor.CONSTANT),
34 | ;
35 |
36 | val textAttributesKey = TextAttributesKey.createTextAttributesKey("coop.rchain.rholang.$name", default)
37 | val attributesDescriptor = AttributesDescriptor(humanName, textAttributesKey)
38 | }
39 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/formatter/RholangSpaceProcessor.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.formatter
2 |
3 | import com.intellij.formatting.Block
4 | import com.intellij.formatting.Spacing
5 | import com.intellij.lang.ASTNode
6 | import com.intellij.openapi.editor.Document
7 | import com.intellij.openapi.util.TextRange
8 | import com.intellij.psi.PsiElement
9 | import com.intellij.psi.codeStyle.CommonCodeStyleSettings
10 | import com.intellij.psi.formatter.common.AbstractBlock
11 | import com.intellij.psi.tree.IElementType
12 | import com.intellij.psi.util.PsiTreeUtil
13 | import coop.rchain.lang.psi.RhoTypes
14 | import coop.rchain.lang.util.PsiTreeHelpUtil
15 |
16 | class RholangSpaceProcessor(private val myNode: ASTNode, private val mySettings: CommonCodeStyleSettings) {
17 |
18 | fun getSpacing(child1: Block?, child2: Block): Spacing? {
19 | if (child1 !is AbstractBlock || child2 !is AbstractBlock) {
20 | return null
21 | }
22 |
23 | val elementType = myNode.elementType
24 | val parentType = if (myNode.treeParent == null) null else myNode.treeParent.elementType
25 | val node1 = child1.node
26 | val type1 = node1.elementType
27 | val node2 = child2.node
28 | val type2 = node2.elementType
29 |
30 | if (type1 === RhoTypes.OPEN_BRACE && (type2 === RhoTypes.PROC || type2 === RhoTypes.CASE)) {
31 | if(parentType !== RhoTypes.NAME_) {
32 | return Spacing.createSpacing(1, 1, 1, false, 0)
33 | }
34 | }
35 | if (type1 === RhoTypes.BITWISE_OR && myNode.treeParent?.treeParent?.elementType !== RhoTypes.NAME_) {
36 | return Spacing.createSpacing(1, 1, 1, false, 0)
37 | }
38 |
39 | if(type1 === RhoTypes.CASE_ || type2 === RhoTypes.CASE_){
40 | return Spacing.createSpacing(1, 1, 1, false, 0)
41 | }
42 |
43 | if(type2 === RhoTypes.CLOSE_BRACE && parentType === RhoTypes.NAME_){
44 | return null
45 | }
46 |
47 | return if (type2 === RhoTypes.CLOSE_BRACE) {
48 | Spacing.createSpacing(1, 1, 1, false, 0)
49 | } else null
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/folding/RholangFoldingBuilder.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.folding
2 |
3 | import com.intellij.lang.ASTNode
4 | import com.intellij.lang.folding.FoldingBuilder
5 | import com.intellij.lang.folding.FoldingDescriptor
6 | import com.intellij.openapi.editor.Document
7 | import com.intellij.openapi.project.DumbAware
8 | import com.intellij.openapi.util.TextRange
9 | import com.intellij.psi.PsiElement
10 | import coop.rchain.lang.psi.RhoTypes
11 | import java.util.*
12 |
13 | class RholangFoldingBuilder : FoldingBuilder, DumbAware {
14 |
15 | override fun buildFoldRegions(node: ASTNode, document: Document): Array {
16 | val descriptors = ArrayList()
17 | appendDescriptors(node.psi, descriptors, document)
18 |
19 | return descriptors.toTypedArray()
20 | }
21 |
22 | private fun appendDescriptors(psi: PsiElement, descriptors: MutableList, document: Document) {
23 | if (isSingleLine(psi, document)) { // don't fold when text is single line
24 | return
25 | }
26 |
27 | val elementType = psi.node.elementType
28 |
29 | if (elementType === RhoTypes.PROC_BLOCK) {
30 | val textRange = psi.node.textRange
31 | val textRange1 = TextRange(textRange.startOffset + 1, textRange.endOffset - 1)
32 | descriptors.add(FoldingDescriptor(psi.node, textRange1))
33 | }
34 |
35 | var child: PsiElement? = psi.firstChild
36 | while (child != null) {
37 | appendDescriptors(child, descriptors, document)
38 | child = child.nextSibling
39 | }
40 | }
41 |
42 |
43 | private fun isSingleLine(element: PsiElement, document: Document): Boolean {
44 | val textRange = element.textRange
45 | return document.getLineNumber(textRange.startOffset) == document.getLineNumber(textRange.endOffset)
46 | }
47 |
48 | override fun getPlaceholderText(node: ASTNode): String? {
49 | return "..."
50 | }
51 |
52 | override fun isCollapsedByDefault(node: ASTNode): Boolean {
53 | return false
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/RhoParserDefinition.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang
2 |
3 | import com.intellij.lang.ASTNode
4 | import com.intellij.lang.ParserDefinition
5 | import com.intellij.lang.PsiParser
6 | import com.intellij.lexer.FlexAdapter
7 | import com.intellij.lexer.Lexer
8 | import com.intellij.openapi.project.Project
9 | import com.intellij.psi.FileViewProvider
10 | import com.intellij.psi.PsiElement
11 | import com.intellij.psi.PsiFile
12 | import com.intellij.psi.TokenType
13 | import com.intellij.psi.tree.IFileElementType
14 | import com.intellij.psi.tree.TokenSet
15 | import coop.rchain.lang.RhoParser
16 | import coop.rchain.lang.psi.RhoFile
17 | import coop.rchain.lang.psi.RhoTypes
18 |
19 | import java.io.Reader
20 |
21 | class RhoParserDefinition : ParserDefinition {
22 |
23 | override fun createLexer(project: Project): Lexer {
24 | return FlexAdapter(RhoLexer(null as Reader?))
25 | }
26 |
27 | override fun getWhitespaceTokens(): TokenSet {
28 | return WHITE_SPACES
29 | }
30 |
31 | override fun getCommentTokens(): TokenSet {
32 | return COMMENTS
33 | }
34 |
35 | override fun getStringLiteralElements(): TokenSet {
36 | return TokenSet.EMPTY
37 | }
38 |
39 | override fun createParser(project: Project): PsiParser {
40 | return RhoParser()
41 | }
42 |
43 | override fun getFileNodeType(): IFileElementType {
44 | return FILE
45 | }
46 |
47 | override fun createFile(viewProvider: FileViewProvider): PsiFile {
48 | return RhoFile(viewProvider)
49 | }
50 |
51 | override fun spaceExistanceTypeBetweenTokens(left: ASTNode, right: ASTNode): ParserDefinition.SpaceRequirements {
52 | return ParserDefinition.SpaceRequirements.MAY
53 | }
54 |
55 | override fun createElement(node: ASTNode): PsiElement {
56 | return RhoTypes.Factory.createElement(node)
57 | }
58 |
59 | companion object {
60 | val WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE)
61 | val COMMENTS = TokenSet.create(RhoTypes.LINE_COMMENT)
62 | val FILE = IFileElementType(RhoLanguage.Companion.INSTANCE)
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/formatter/RholangIndentProcessor.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.formatter
2 |
3 | import com.intellij.formatting.FormattingMode
4 | import com.intellij.formatting.Indent
5 | import com.intellij.lang.ASTNode
6 | import com.intellij.psi.codeStyle.CommonCodeStyleSettings
7 | import coop.rchain.lang.psi.RhoTypes
8 | import coop.rchain.lang.util.PsiTreeHelpUtil
9 |
10 | class RholangIndentProcessor(private val settings: CommonCodeStyleSettings) {
11 |
12 | fun getChildIndent(node: ASTNode, mode: FormattingMode): Indent {
13 | val elementType = node.elementType
14 | val parent = node.treeParent
15 | val parentType = parent?.elementType
16 | val grandParent = parent?.treeParent
17 | val grandParentType = grandParent?.elementType
18 | val prevSibling = PsiTreeHelpUtil.getPrevSiblingSkipWhiteSpacesAndComments(node)
19 | val prevSiblingType = prevSibling?.elementType
20 | if (parent == null || grandParent == null || grandParent.treeParent == null) {
21 | return Indent.getNoneIndent()
22 | }
23 |
24 | // if (grandParentType === RhoTypes.BIND_PAREN) {
25 | // return Indent.getContinuationIndent()
26 | // }
27 |
28 | // if (elementType === RhoTypes.PM_BRANCH) {
29 | // return Indent.getNormalIndent()
30 | // }
31 |
32 | if (parentType === RhoTypes.PROC_PAREN_OPTION ) {
33 | return if (elementType === RhoTypes.OPEN_PAREN || elementType === RhoTypes.CLOSE_PAREN) {
34 | Indent.getNoneIndent()
35 | } else Indent.getContinuationIndent()
36 | }
37 |
38 | if (parentType === RhoTypes.PROC_BLOCK || parentType === RhoTypes.PROC_BLOCK || parentType === RhoTypes.CASE_BLOCK ) {
39 | return if (elementType === RhoTypes.OPEN_BRACE || elementType === RhoTypes.CLOSE_BRACE) {
40 | Indent.getNoneIndent()
41 | } else Indent.getNormalIndent()
42 | }
43 |
44 | // return if (grandParentType === RhoTypes.QUANTITY_ && parentType === RhoTypes.PROC) {
45 | // Indent.getContinuationIndent()
46 | // } else Indent.getNoneIndent()
47 | return Indent.getNoneIndent()
48 |
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/RhoColorSettingsPage.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang
2 |
3 | import com.intellij.application.options.colors.InspectionColorSettingsPage
4 | import com.intellij.openapi.options.colors.ColorDescriptor
5 | import com.intellij.openapi.options.colors.ColorSettingsPage
6 | import com.intellij.psi.codeStyle.DisplayPriority
7 | import com.intellij.psi.codeStyle.DisplayPrioritySortable
8 |
9 | class RhoColorSettingsPage : ColorSettingsPage, InspectionColorSettingsPage, DisplayPrioritySortable {
10 | private val ATTRS = RhoColor.values().map { it.attributesDescriptor }.toTypedArray()
11 |
12 | private val ANNOTATOR_TAGS = RhoColor.values().associateBy({ it.name }, { it.textAttributesKey })
13 |
14 | private val DEMO_TEXT by lazy {
15 | """/**
16 | * Rholang is a behaviorally typed, concurrent programming language,
17 | * with a focus on message-passing and formally modeled by the ρ-calculus,
18 | * a reflective, higher-order extension of the π-calculus.
19 | */
20 | new helloworld in {
21 | contract helloworld( world ) = {
22 | for( msg <- world ) {
23 | // Hello from Rholang!
24 | print( msg )
25 | }
26 | } |
27 | /*
28 | * It is designed to be used to implement protocols and "smart contracts"
29 | * on a general-purpose blockchain, but could be used in other settings as well.
30 | */
31 | new world in {
32 | helloworld!( world ) |
33 | world!( "Hello World" )
34 | }
35 | }
36 | """
37 | }
38 |
39 | override fun getDisplayName() = "Rholang"
40 | override fun getIcon() = RhoIcons.DEFAULT
41 | override fun getAttributeDescriptors() = ATTRS
42 | override fun getColorDescriptors(): Array = ColorDescriptor.EMPTY_ARRAY
43 | override fun getHighlighter() = RhoSyntaxHighlighter()
44 | override fun getAdditionalHighlightingTagToDescriptorMap() = ANNOTATOR_TAGS
45 | override fun getDemoText() = DEMO_TEXT
46 | override fun getPriority(): DisplayPriority = DisplayPriority.KEY_LANGUAGE_SETTINGS
47 | }
48 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/formatter/RholangBlock.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang.formatter
2 |
3 | import com.intellij.formatting.*
4 | import com.intellij.formatting.templateLanguages.BlockWithParent
5 | import com.intellij.lang.ASTNode
6 | import com.intellij.psi.codeStyle.CodeStyleSettings
7 | import com.intellij.psi.formatter.FormatterUtil
8 | import com.intellij.psi.formatter.common.AbstractBlock
9 |
10 | import java.util.ArrayList
11 |
12 | class RholangBlock(node: ASTNode, wrap: Wrap?, alignment: Alignment?, private val mySettings: CodeStyleSettings, private val myContext: RholangBlockContext) : AbstractBlock(node, wrap, alignment), BlockWithParent {
13 | private val myIndentProcessor: RholangIndentProcessor
14 | private val myIndet: Indent
15 | private val mySpacingProcessor: RholangSpaceProcessor
16 | private var myParent: BlockWithParent? = null
17 |
18 | init {
19 | myIndentProcessor = RholangIndentProcessor(myContext.rholangSettings)
20 | myIndet = myIndentProcessor.getChildIndent(node, myContext.mode)
21 | mySpacingProcessor = RholangSpaceProcessor(node, myContext.rholangSettings)
22 | }
23 |
24 | override fun buildChildren(): List {
25 | if (isLeaf) {
26 | return AbstractBlock.EMPTY
27 | }
28 |
29 | val blockChildren = ArrayList()
30 | var childNode: ASTNode? = node.firstChildNode
31 | while (childNode != null) {
32 | if (!FormatterUtil.containsWhiteSpacesOnly(childNode)) {
33 | val childBlock = RholangBlock(childNode, Wrap.createWrap(WrapType.NONE, false), null, mySettings, myContext)
34 | childBlock.setParent(this)
35 | blockChildren.add(childBlock)
36 | }
37 | childNode = childNode.treeNext
38 | }
39 | return blockChildren
40 | }
41 |
42 | override fun getIndent(): Indent? {
43 | return myIndet
44 | }
45 |
46 | override fun getSpacing(child1: Block?, child2: Block): Spacing? {
47 | return mySpacingProcessor.getSpacing(child1, child2)
48 | }
49 |
50 | override fun isLeaf(): Boolean {
51 | return false
52 | }
53 |
54 | override fun getParent(): BlockWithParent? {
55 | return myParent
56 | }
57 |
58 | override fun setParent(newParent: BlockWithParent) {
59 | myParent = newParent
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/testData/ide/formatter/complexFormatted.rho:
--------------------------------------------------------------------------------
1 | new testResult, updateTestResult in {
2 | testResult!(true) |
3 | contract updateTestResult(@bool, return) = {
4 | for(@r <- testResult) {
5 | match [r, bool] {
6 | [true, true] => {
7 | testResult!(true) |
8 | return!(true)
9 | }
10 | _ => {
11 | testResult!(false) |
12 | return!(false)
13 | }
14 | }
15 | }
16 | } |
17 | contract @"CoatCheckDemo"(_) = {
18 | new MakeCoatCheck in {
19 | contract MakeCoatCheck(ret) = {
20 | new port, table in {
21 | ret!(*port) |
22 | for(@"new", @arg, ack <= port) {
23 | new ticket in {
24 | ack!(*ticket) |
25 | @{*ticket | *table}!(arg)
26 | }
27 | } |
28 | for(@"get", @arg, ack <= port) {
29 | for (@value <- @{arg | *table}) {
30 | @{arg | *table}!(value) |
31 | ack!(value)
32 | }
33 | } |
34 | for(@"set", @arg1, @arg2, ack <= port) {
35 | for (_ <- @{arg1 | *table}) {
36 | @{arg1 | *table}!(arg2) |
37 | ack!(true)
38 | }
39 | }
40 | }
41 | } |
42 | // Usage
43 | new ret, get, set in {
44 | MakeCoatCheck!(*ret) |
45 | for (cc <- ret) {
46 | // Creates new cell with initial value 0
47 | cc!("new", 0, *ret) |
48 | for (ticket <- ret) {
49 | contract get(return) = {
50 | cc!("get", *ticket, *return)
51 | } |
52 | contract set(@value, return) = {
53 | cc!("set", *ticket, value, *return)
54 | } |
55 | get!(*ret) |
56 | for(@r <- ret) {
57 | updateTestResult!(r == 0, *ret) |
58 | for(_ <- ret){
59 | set!(1, *ret) |
60 | for(_ <- ret) {
61 | get!(*ret) |
62 | for(@r <- ret) {
63 | updateTestResult!(r == 1, *ret)
64 | }
65 | }
66 | }
67 | }
68 | }
69 | }
70 | }
71 | }
72 | } |
73 | @"CoatCheckDemo"!(Nil)
74 | }
75 |
--------------------------------------------------------------------------------
/resources/META-INF/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 | coop.rchain.lang
3 | Rholang
4 | 0.2.0
5 | RChain.coop
6 |
7 | Rholang.
9 |
10 | Official language for RChain distributed virtual machine.
11 | ]]>
12 |
13 |
15 | 0.2.0 @AbnerZheng:
16 |
17 | - Updated grammar for Rholang Mercury release.
18 |
19 |
20 | 0.1.0 @AbnerZheng:
21 |
22 | - Implemented formatting feature.
23 | - Updated grammar (quick fix before Mercury) @tgrospic
24 |
25 |
26 | 0.0.4 @AbnerZheng:
27 |
28 | - Implemented folding feature.
29 | - Added initial tests.
30 |
31 |
32 | 0.0.3:
33 |
34 | - Syntax: Contracts as processes (recursive).
35 | - Syntax: Fix arithmetic operators.
36 | - New file icon.
37 |
38 |
39 | 0.0.2: Update plugin name.
40 | 0.0.1: Syntax highlighting and comments support. Initial version.
41 |
42 | ]]>
43 |
44 |
45 |
46 |
47 |
48 |
50 | com.intellij.modules.lang
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/Rho.flex:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang;
2 |
3 | import com.intellij.lexer.FlexLexer;
4 | import com.intellij.psi.tree.IElementType;
5 |
6 | import static com.intellij.psi.TokenType.BAD_CHARACTER;
7 | import static com.intellij.psi.TokenType.WHITE_SPACE;
8 | import static coop.rchain.lang.psi.RhoTypes.*;
9 | %%
10 |
11 | %{
12 | public RhoLexer() {
13 | this((java.io.Reader)null);
14 | }
15 | %}
16 |
17 | %public
18 | %class RhoLexer
19 | %implements FlexLexer
20 | %function advance
21 | %type IElementType
22 | %unicode
23 |
24 | EOL=\R
25 | WHITE_SPACE=\s+
26 |
27 | SPACE=[ \t\n\x0B\f\r]+
28 | LINE_COMMENT = "//".*
29 | INTEGER=[0-9]+(\.[0-9]*)?
30 | ID_NAME=([a-zA-Z'][a-zA-Z_0-9']*)|([_a-zA-Z0-9']+)
31 | StringLit=('([^'\\]|\\.)*'|\"([^\"\\]|\\.)*\")
32 | URI=`([^`\\]|\\[`\\])*`
33 |
34 | %%
35 | {
36 | {WHITE_SPACE} { return WHITE_SPACE; }
37 |
38 | "contract" { return CONTRACT; }
39 | "select" { return SELECT; }
40 | "match" { return MATCH; }
41 | "for" { return FOR; }
42 | "new" { return NEW; }
43 | "if" { return IF; }
44 | "else" { return ELSE; }
45 | "in" { return IN; }
46 | "false" { return FALSE; }
47 | "true" { return TRUE; }
48 | "Nil" { return NIL; }
49 | "=>" { return FAT_ARROW; }
50 | "->" { return THIN_ARROW; }
51 | "." { return DOT; }
52 | "&" { return BITWISE_AND; }
53 | "|" { return BITWISE_OR; }
54 | "^" { return BITWISE_XOR; }
55 | "..." { return TRIPLE_DOT; }
56 | ".." { return DOUBLE_DOT; }
57 | "::" { return DOUBLE_COLON; }
58 | ":" { return COLON; }
59 | "+" { return PLUS; }
60 | "-" { return MINUS; }
61 | "*" { return MULTIPLY; }
62 | "/" { return DIVIDE; }
63 | "%" { return REMAINDER; }
64 | "<<=" { return ASSIGN_LEFT_SHIFT; }
65 | ">>=" { return ASSIGN_RIGHT_SHIFT; }
66 | "==" { return EQUAL; }
67 | "=" { return ASSIGN; }
68 | "!=" { return NOT_EQUAL; }
69 | "<=" { return LESS_THAN_OR_EQUAL; }
70 | "<" { return LESS_THAN; }
71 | ">=" { return GREATER_THAN_OR_EQUAL; }
72 | ">" { return GREATER_THAN; }
73 | "!" { return NOT; }
74 | "~" { return BOX; }
75 | "@" { return AT; }
76 | "'" { return SINGLE_QUOTE; }
77 | "$" { return DOLLAR; }
78 | "#" { return HASH; }
79 | "[" { return OPEN_SQUARE_BRACKET; }
80 | "]" { return CLOSE_SQUARE_BRACKET; }
81 | "(" { return OPEN_PAREN; }
82 | ")" { return CLOSE_PAREN; }
83 | "{" { return OPEN_BRACE; }
84 | "}" { return CLOSE_BRACE; }
85 | "," { return COMMA; }
86 | ";" { return SEMICOLON; }
87 | "_" { return UNDERSCORE; }
88 |
89 | {SPACE} { return SPACE; }
90 | {LINE_COMMENT} { return LINE_COMMENT; }
91 | {INTEGER} { return INTEGER; }
92 | {ID_NAME} { return ID_NAME; }
93 | {StringLit} { return STRINGLIT; }
94 | {URI} { return URI; }
95 |
96 | }
97 |
98 | [^] { return BAD_CHARACTER; }
99 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/RhoSyntaxHighlighter.kt:
--------------------------------------------------------------------------------
1 | package coop.rchain.lang
2 |
3 | import com.intellij.lexer.FlexAdapter
4 | import com.intellij.lexer.Lexer
5 | import com.intellij.openapi.editor.colors.TextAttributesKey
6 | import com.intellij.openapi.fileTypes.SyntaxHighlighter
7 | import com.intellij.openapi.fileTypes.SyntaxHighlighterBase
8 | import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory
9 | import com.intellij.openapi.project.Project
10 | import com.intellij.openapi.vfs.VirtualFile
11 | import com.intellij.psi.tree.IElementType
12 | import coop.rchain.lang.psi.RhoTypes.*
13 | import java.io.Reader
14 |
15 | class RhoSyntaxHighlighterFactory : SyntaxHighlighterFactory() {
16 | override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?): SyntaxHighlighter = RhoSyntaxHighlighter()
17 | }
18 |
19 | class RhoSyntaxHighlighter : SyntaxHighlighterBase() {
20 |
21 | override fun getHighlightingLexer(): Lexer = FlexAdapter(RhoLexer(null as Reader?))
22 |
23 | override fun getTokenHighlights(tokenType: IElementType): Array =
24 | pack(map(tokenType)?.textAttributesKey)
25 |
26 | companion object {
27 | fun map(tokenType: IElementType?): RhoColor? = when (tokenType) {
28 | TRUE, FALSE,
29 | CONTRACT, MATCH, FOR, NIL, NEW, SELECT,
30 | IF, IN, ELSE,
31 | UNDERSCORE -> RhoColor.KEYWORD
32 |
33 | VAR -> RhoColor.IDENTIFIER
34 |
35 | STRINGLIT -> RhoColor.STRING
36 | URI -> RhoColor.NUMBER
37 | INTEGER -> RhoColor.NUMBER
38 | RHO_NAME -> RhoColor.RHO_NAME
39 |
40 |
41 | LINE_COMMENT -> RhoColor.LINE_COMMENT
42 | BLOCK_COMMENT -> RhoColor.BLOCK_COMMENT
43 |
44 | OPEN_PAREN, CLOSE_PAREN -> RhoColor.PARENTHESIS
45 | OPEN_BRACE, CLOSE_BRACE -> RhoColor.BRACES
46 | OPEN_SQUARE_BRACKET, CLOSE_SQUARE_BRACKET -> RhoColor.BRACKETS
47 |
48 | SEMICOLON -> RhoColor.SEMICOLON
49 | COMMA -> RhoColor.COMMA
50 |
51 | // Operators
52 | HASH, DOLLAR, AT -> RhoColor.OPERATORS
53 | TRIPLE_DOT -> RhoColor.OPERATORS
54 | DOUBLE_DOT -> RhoColor.OPERATORS
55 | ASSIGN_RIGHT_SHIFT -> RhoColor.OPERATORS
56 | ASSIGN_LEFT_SHIFT -> RhoColor.OPERATORS
57 | FAT_ARROW -> RhoColor.OPERATORS
58 | THIN_ARROW -> RhoColor.OPERATORS
59 | DOT -> RhoColor.OPERATORS
60 | BITWISE_AND -> RhoColor.OPERATORS
61 | BITWISE_OR -> RhoColor.OPERATORS
62 | BITWISE_XOR -> RhoColor.OPERATORS
63 | DOUBLE_COLON -> RhoColor.OPERATORS
64 | COLON -> RhoColor.OPERATORS
65 | PLUS -> RhoColor.OPERATORS
66 | MINUS -> RhoColor.OPERATORS
67 | MULTIPLY -> RhoColor.OPERATORS
68 | DIVIDE -> RhoColor.OPERATORS
69 | REMAINDER -> RhoColor.OPERATORS
70 | EQUAL -> RhoColor.OPERATORS
71 | ASSIGN -> RhoColor.OPERATORS
72 | NOT_EQUAL -> RhoColor.OPERATORS
73 | LESS_THAN_OR_EQUAL -> RhoColor.OPERATORS
74 | LESS_THAN -> RhoColor.OPERATORS
75 | GREATER_THAN_OR_EQUAL -> RhoColor.OPERATORS
76 | GREATER_THAN -> RhoColor.OPERATORS
77 | NOT -> RhoColor.OPERATORS
78 | BOX -> RhoColor.OPERATORS
79 | SINGLE_QUOTE -> RhoColor.OPERATORS
80 | OPEN_SQUARE_BRACKET -> RhoColor.OPERATORS
81 | CLOSE_SQUARE_BRACKET -> RhoColor.OPERATORS
82 | OPEN_PAREN -> RhoColor.OPERATORS
83 | CLOSE_PAREN -> RhoColor.OPERATORS
84 | OPEN_BRACE -> RhoColor.OPERATORS
85 | CLOSE_BRACE -> RhoColor.OPERATORS
86 | COMMA -> RhoColor.OPERATORS
87 | SEMICOLON -> RhoColor.OPERATORS
88 |
89 | else -> null
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/rholang.cf:
--------------------------------------------------------------------------------
1 | -- https://github.com/rchain/rchain/blob/1f5450e8e54b2bbce7d81206eb8d4fdd6bc96797/rholang/src/main/bnfc/rholang.cf
2 |
3 | -- Top level contract declaration
4 | DContr. Contr ::= Proc1 ;
5 |
6 | -- Processes
7 | PNil. Proc4 ::= "Nil" ;
8 | PValue. Proc4 ::= Value;
9 | PDrop. Proc3 ::= "*" Chan ;
10 | PLift. Proc2 ::= Chan "!" "(" [Proc] ")" ;
11 | PInput. Proc1 ::= "for" "(" [Bind] ")" "{" Proc "}" ;
12 | PChoice. Proc1 ::= "select" "{" [CBranch] "}" ;
13 | PMatch. Proc1 ::= "match" Proc "with" [PMBranch] ;
14 | PNew. Proc1 ::= "new" [Var] "in" Proc1 ;
15 | PConstr. Proc1 ::= Var "(" [Proc] ")" ;
16 | PContr. Proc1 ::= "contract" Var "(" [CPattern] ")" "=" "{" Proc "}" ;
17 | PPar. Proc ::= Proc "|" Proc1 ;
18 | separator Proc "," ;
19 | _. Proc ::= Proc1 ;
20 | _. Proc1 ::= Proc2 ;
21 | _. Proc2 ::= Proc3 ;
22 | _. Proc3 ::= Proc4 ;
23 | _. Proc4 ::= "{" Proc "}" ;
24 |
25 | -- Channels
26 | CVar. Chan ::= Var ;
27 | CQuote. Chan ::= "@" Proc3 ;
28 |
29 | -- Variable binding
30 | InputBind. Bind ::= CPattern "<-" Chan ;
31 | CondInputBind. Bind ::= CPattern "<-" Chan "if" Proc ;
32 | separator nonempty Bind ";" ;
33 |
34 | -- Pattern match branches
35 | PatternMatch. PMBranch ::= PPattern "=>" "{" Proc "}" ;
36 | separator nonempty PMBranch "" ;
37 |
38 | -- Choice branch
39 | Choice. CBranch ::= "case" [Bind] "=>" "{" Proc "}" ;
40 | separator nonempty CBranch "" ;
41 |
42 | -- Quantity
43 | QTrue. RhoBool ::= "true" ;
44 | QFalse. RhoBool ::= "false" ;
45 | QBool. Quantity7 ::= RhoBool ;
46 | QInt. Quantity7 ::= Integer ;
47 | QDouble. Quantity7 ::= Double ;
48 | QString. Quantity7 ::= String;
49 | QVar. Quantity7 ::= Var;
50 | QMap. Quantity7 ::= "Map()" ;
51 | QDot. Quantity6 ::= Quantity7 "." Var "(" [Quantity] ")" ;
52 | QNeg. Quantity5 ::= "-" Quantity6 ;
53 | QMult. Quantity4 ::= Quantity4 "*" Quantity5 ;
54 | QDiv. Quantity4 ::= Quantity4 "/" Quantity5 ;
55 | QAdd. Quantity3 ::= Quantity3 "+" Quantity4 ;
56 | QMinus. Quantity3 ::= Quantity3 "-" Quantity4 ;
57 | QLt. Quantity2 ::= Quantity2 "<" Quantity3 ;
58 | QLte. Quantity2 ::= Quantity2 "<=" Quantity3 ;
59 | QGt. Quantity2 ::= Quantity2 ">" Quantity3 ;
60 | QGte. Quantity2 ::= Quantity2 ">=" Quantity3 ;
61 | QEq. Quantity1 ::= Quantity1 "==" Quantity2 ;
62 | QNeq. Quantity1 ::= Quantity1 "!=" Quantity2 ;
63 | _. Quantity ::= Quantity1 ;
64 | _. Quantity1 ::= Quantity2 ;
65 | _. Quantity2 ::= Quantity3 ;
66 | _. Quantity3 ::= Quantity4 ;
67 | _. Quantity4 ::= Quantity5 ;
68 | _. Quantity5 ::= Quantity6 ;
69 | _. Quantity6 ::= Quantity7 ;
70 | _. Quantity7 ::= "(" Quantity ")" ;
71 | separator Quantity "," ;
72 |
73 | -- Values
74 | VQuant. Value ::= Quantity ;
75 | EChar. Value ::= Char ;
76 | ETuple. Value ::= "[" [Proc] "]" ;
77 |
78 | -- EStruct. Entity ::= Struct ;
79 | -- ECollect. Entity ::= Collect ;
80 | -- StructConstr. Struct ::= Var "{" [Proc] "}" ;
81 | -- CString. Collect ::= String ;
82 | -- EDate. Entity ::= Datetime ;
83 | -- CArray. Collect ::= Array ;
84 | -- CList. Collect ::= List ;
85 |
86 | -- Variable patterns
87 | VarPtVar. VarPattern ::= Var ;
88 | VarPtWild. VarPattern ::= "_" ;
89 | separator VarPattern "," ;
90 |
91 | -- Process patterns
92 | PPtVal. PPattern4 ::= ValPattern ;
93 | PPtVar. PPattern4 ::= VarPattern ;
94 | separator PPattern "," ;
95 | coercions PPattern 4 ;
96 |
97 | -- Channel patterns
98 | CPtVar. CPattern ::= VarPattern ;
99 | CValPtrn. CPattern ::= ValPattern ;
100 | CPtQuote. CPattern ::= "@" PPattern3 ;
101 | separator CPattern "," ;
102 |
103 | -- Value patterns
104 |
105 | -- We only allow for constants in pattern matches
106 | -- unlike for Procs which can have arbitrary operations
107 | VPtTuple. ValPattern ::= "[" [PPattern] "]" ;
108 | VPtTrue. ValPattern ::= "true" ;
109 | VPtFalse. ValPattern ::= "false" ;
110 | VPtInt. ValPattern ::= Integer ;
111 | VPtDbl. ValPattern ::= Double ;
112 | VPtNegInt. ValPattern ::= "-" Integer;
113 | VPtNegDbl. ValPattern ::= "-" Double;
114 | VPtStr. ValPattern ::= String ;
115 |
116 | -- Variables
117 | token Var ((letter | '_')(letter | digit | '_' | '\'')*) ;
118 |
119 | separator nonempty Var "," ;
120 |
121 | comment "//" ;
122 | comment "/*" "*/" ;
123 |
--------------------------------------------------------------------------------
/src/rholang-mercury.cf:
--------------------------------------------------------------------------------
1 | -- A program is just a process. We put the coercions first, because that's what
2 | -- bnfc uses to determine the starting production.
3 | _. Proc ::= Proc1 ;
4 | _. Proc1 ::= Proc2 ;
5 | _. Proc2 ::= Proc3 ;
6 | _. Proc3 ::= Proc4 ;
7 | _. Proc4 ::= Proc5 ;
8 | _. Proc5 ::= Proc6 ;
9 | _. Proc6 ::= Proc7 ;
10 | _. Proc7 ::= Proc8 ;
11 | _. Proc8 ::= Proc9 ;
12 | _. Proc9 ::= Proc10 ;
13 | _. Proc10 ::= Proc11 ;
14 | _. Proc11 ::= Proc12 ;
15 | _. Proc12 ::= Proc13 ;
16 | _. Proc13 ::= Proc14 ;
17 | _. Proc14 ::= Proc15 ;
18 | _. Proc15 ::= Proc16 ;
19 | _. Proc16 ::= "{" Proc "}" ;
20 |
21 | -- Processes
22 | -- In general the expression style processes are higher precedence.
23 | -- Expression style is anything that necessary resolves to a single ground value
24 | -- or a collection.
25 | PGround. Proc16 ::= Ground ;
26 | PCollect. Proc16 ::= Collection ;
27 | PVar. Proc16 ::= ProcVar ;
28 | PVarRef. Proc13 ::= VarRefKind Var ;
29 | PNil. Proc16 ::= "Nil" ;
30 | PSimpleType. Proc16 ::= SimpleType ;
31 | PNegation. Proc15 ::= "~" Proc15 ;
32 | PConjunction. Proc14 ::= Proc14 "/\\" Proc15 ;
33 | PDisjunction. Proc13 ::= Proc13 "\\/" Proc14 ;
34 | PEval. Proc12 ::= "*" Name ;
35 | PMethod. Proc11 ::= Proc11 "." Var "(" [Proc] ")" ;
36 | PExprs. Proc11 ::= "(" Proc4 ")" ;
37 | PNot. Proc10 ::= "not" Proc10 ;
38 | PNeg. Proc10 ::= "-" Proc10 ;
39 | PMult. Proc9 ::= Proc9 "*" Proc10 ;
40 | PDiv. Proc9 ::= Proc9 "/" Proc10 ;
41 | PPercentPercent. Proc9 ::= Proc9 "%%" Proc10 ;
42 | PAdd. Proc8 ::= Proc8 "+" Proc9 ;
43 | PMinus. Proc8 ::= Proc8 "-" Proc9 ;
44 | PPlusPlus. Proc8 ::= Proc8 "++" Proc9 ;
45 | PMinusMinus. Proc8 ::= Proc8 "--" Proc9 ;
46 | PLt. Proc7 ::= Proc7 "<" Proc8 ;
47 | PLte. Proc7 ::= Proc7 "<=" Proc8 ;
48 | PGt. Proc7 ::= Proc7 ">" Proc8 ;
49 | PGte. Proc7 ::= Proc7 ">=" Proc8 ;
50 | PMatches. Proc6 ::= Proc7 "matches" Proc7 ;
51 | PEq. Proc6 ::= Proc6 "==" Proc7 ;
52 | PNeq. Proc6 ::= Proc6 "!=" Proc7 ;
53 | PAnd. Proc5 ::= Proc5 "and" Proc6 ;
54 | POr. Proc4 ::= Proc4 "or" Proc5 ;
55 | PSend. Proc3 ::= Name Send "(" [Proc] ")" ;
56 | PContr. Proc2 ::= "contract" Name "(" [Name] NameRemainder")" "=" "{" Proc "}" ;
57 | PInput. Proc2 ::= "for" "(" Receipt ")" "{" Proc "}" ;
58 | PChoice. Proc2 ::= "select" "{" [Branch] "}" ;
59 | PMatch. Proc2 ::= "match" Proc4 "{" [Case] "}" ;
60 | PBundle. Proc2 ::= Bundle "{" Proc "}" ;
61 | PIf. Proc1 ::= "if" "(" Proc ")" Proc2 ;
62 | -- Use precedence to force braces around an interior if.
63 | PIfElse. Proc1 ::= "if" "(" Proc ")" Proc2 "else" Proc1 ;
64 | PNew. Proc1 ::= "new" [NameDecl] "in" Proc1 ;
65 | PPar. Proc ::= Proc "|" Proc1 ;
66 |
67 | separator Proc "," ;
68 |
69 | -- Process variables
70 | ProcVarWildcard. ProcVar ::= "_" ;
71 | ProcVarVar. ProcVar ::= Var ;
72 |
73 | -- Names
74 | NameWildcard. Name ::= "_" ;
75 | NameVar. Name ::= Var ;
76 | NameQuote. Name ::= "@" Proc12 ;
77 | separator Name "," ;
78 |
79 | -- Bundle
80 | BundleWrite. Bundle ::= "bundle+" ;
81 | BundleRead. Bundle ::= "bundle-" ;
82 | BundleEquiv. Bundle ::= "bundle0" ;
83 | BundleReadWrite. Bundle ::= "bundle" ;
84 |
85 | -- Receipt
86 | ReceiptLinear. Receipt ::= ReceiptLinearImpl ;
87 | ReceiptRepeated. Receipt ::= ReceiptRepeatedImpl ;
88 |
89 | -- Linear Receipts
90 | LinearSimple. ReceiptLinearImpl ::= [LinearBind] ;
91 | -- Implementing this will be tricky.
92 | -- for (x <- a; y <- b if *x)
93 | -- LinearCond. Linear ::= [LinearBind] "if" Proc ;
94 |
95 | -- Single Linear Bind
96 | LinearBindImpl. LinearBind ::= [Name] NameRemainder "<-" Name ;
97 | separator nonempty LinearBind ";" ;
98 |
99 | -- Repeated Receipts
100 | RepeatedSimple. ReceiptRepeatedImpl ::= [RepeatedBind] ;
101 | -- Single Repeated Bind
102 | RepeatedBindImpl. RepeatedBind ::= [Name] NameRemainder "<=" Name ;
103 | separator nonempty RepeatedBind ";" ;
104 |
105 | -- Types of Send:
106 | SendSingle. Send ::= "!" ;
107 | SendMultiple. Send ::= "!!" ;
108 |
109 | -- Select Branches
110 | BranchImpl. Branch ::= ReceiptLinearImpl "=>" Proc3 ;
111 | separator nonempty Branch "" ;
112 |
113 | -- Match Cases
114 | CaseImpl. Case ::= Proc13 "=>" Proc3 ;
115 | separator nonempty Case "" ;
116 |
117 | -- Name Declarations.
118 | -- Eventually will have IOPairs.
119 | NameDeclSimpl. NameDecl ::= Var ;
120 | NameDeclUrn. NameDecl ::= Var "(" Uri ")" ;
121 | separator nonempty NameDecl "," ;
122 |
123 | -- Booleans:
124 | BoolTrue. Bool ::= "true" ;
125 | BoolFalse. Bool ::= "false" ;
126 | -- Ground types:
127 | GroundBool. Ground ::= Bool ;
128 | GroundInt. Ground ::= Integer ;
129 | GroundString. Ground ::= String ;
130 | GroundUri. Ground ::= Uri ;
131 | token Uri ('`' ((char - ["\\`"]) | ('\\' ["`\\"]))* '`') ;
132 | -- Collections:
133 | CollectList. Collection ::= "[" [Proc] ProcRemainder "]" ;
134 | CollectTuple. Collection ::= Tuple;
135 | CollectSet. Collection ::= "Set" "(" [Proc] ")" ;
136 | CollectMap. Collection ::= "{" [KeyValuePair] "}" ;
137 | KeyValuePairImpl. KeyValuePair ::= Proc ":" Proc ;
138 | separator KeyValuePair "," ;
139 |
140 | TupleSingle. Tuple ::= "(" Proc ",)" ;
141 | TupleMultiple. Tuple ::= "(" Proc "," [Proc] ")" ;
142 |
143 | -- Remainders:
144 | ProcRemainderVar. ProcRemainder ::= "..." ProcVar ;
145 | ProcRemainderEmpty. ProcRemainder ::= "" ;
146 | NameRemainderVar. NameRemainder ::= "..." "@" ProcVar ;
147 | NameRemainderEmpty. NameRemainder ::= "" ;
148 |
149 | -- VarRefKind:
150 | VarRefKindProc. VarRefKind ::= "=" ;
151 | VarRefKindName. VarRefKind ::= "=" "*" ;
152 |
153 | -- Simple Types:
154 | SimpleTypeBool. SimpleType ::= "Bool" ;
155 | SimpleTypeInt. SimpleType ::= "Int" ;
156 | SimpleTypeString. SimpleType ::= "String" ;
157 | SimpleTypeUri. SimpleType ::= "Uri" ;
158 | SimpleTypeByteArray. SimpleType ::= "ByteArray" ;
159 |
160 |
161 | token Var (((letter | '\'') (letter | digit | '_' | '\'')*)|(('_') (letter | digit | '_' | '\'')+)) ;
162 |
163 | -- Comments:
164 | comment "//" ;
165 | comment "/*" "*/" ;
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Rholang IntelliJ IDEA language plugin
2 |
3 | ![beta][beta-badge]
4 |
5 | This is the early stage of editor support for [Rholang][rho-github]. :smile:
6 |
7 | For now, it has only support for syntax highlighting. I tried to make parser more forgiving so it can highlight wider range of correct programs. With more context information from compiler it could be much more precise.
8 |
9 | > **Rholang** is a fully featured, general purpose, Turing-complete programming language built from the rho-calculus. It is a behaviorally typed, **r**-eflective, **h**-igher **o**-rder process language and the official smart contracting language of [RChain][rchain-coop]. Its purpose is to concretize fine-grained, programmatic concurrency. [RChain Architecture][arch-rholang]
10 |
11 | Rholang is currently in active development and syntax can slightly change. Current version of plugin follows this version of [Rho grammar][rho-bnf-origin] and available examples.
12 |
13 | I found interesting that many grammar rules have a strong gravity towards `Proc`ess :cyclone: but that should not be strange for π-calculus, _λ-expression_ is not the main _actor_ here. [Mobile process calculi for programming the new blockchain][tuplespaces-to-picalculus]
14 |
15 | Programmers in concurrent languages such as Erlang/Elixir say that one of the hardest problems is to coordinate the names (locations) of processes. It seems that Rholang with [Namespace logic][arch-namespace-logic] looks like a great solution for coordination of resources.
16 |
17 | With all this sweet superpowers, that comes with the Rholang compiler and type checker, it will be a pleasure to write smart contracts. :lollipop:
18 |
19 | ## Configure custom colors on the settings page
20 |
21 | Maybe you want to set color for _Bind parameter_ which has no default value.
22 |
23 | 
24 |
25 | ## Install
26 |
27 | From [JetBrains Plugins Repository][rho-idea-plugin] searchable inside the editor.
28 |
29 | Or download **rholang-idea.jar** from the [latest release][releases] and install through [File > Settings > Plugins][idea-install-from-disk] menu.
30 |
31 | ## [Contributing](./CONTRIBUTING.md)
32 |
33 | Any feedback, suggestions, bugs, testing, pull-requests, issues are very welcome. :smile:
34 |
35 | ### Development
36 |
37 | - setup [IntelliJ dev-plugin prerequisites][idea-dev-setup]
38 | - generate Java parser from `Rho.bnf` through the file context menu [Generate Parser Code][idea-gen-parser]
39 | - generate Java lexer from `Rho.flex` through the file context menu [Run JFlex Generator][idea-gen-lexer] (choose _out_ folder or any folder outside the project where jflex.jar will be downloaded)
40 | - build the project (choose _IntelliJ SDK_ and language level _8_)
41 | - create new Plugin Run configuration with default setup
42 | - run/debug in a separate editor
43 | - optionally, to keep formatting consistent install plugin for [EditorConfig][editor-config]
44 |
45 | ### Test
46 |
47 | IntelliJ has provided testing framework. This framework simplifies verification. For more details, you can read [IntelliJ Platform SDK DevGuide][idea-test-guide].
48 |
49 | #### How to use
50 |
51 | Just as using JUnit, there is a 'run' button on the left of the class or test case. You can click this button to run or debug. Also, _right-click_ on the `test` folder has option to _Run/Debug 'All Tests'_.
52 |
53 | ### Deployment
54 |
55 | - generate _jar_ file through the project root context menu [Prepare Plugin Module ... For Deployment][idea-deploy] (in `.idea` folder)
56 | - upload _jar_ to [JetBrains Plugins Repository][rho-idea-plugin]
57 |
58 | ### TODO
59 |
60 | - write more tests and configure CI
61 | - write [Completion Contributor][idea-completion]
62 | - write [Reference Contributor][idea-reference]
63 | - add [plugin actions][idea-plugin-actions]
64 | - connect with the compiler (get semantic info)
65 | - ...
66 |
67 | ## Release Notes
68 |
69 | ### 0.2.0 [@AbnerZheng](https://github.com/AbnerZheng)
70 | - Updated grammar for Rholang Mercury release.
71 |
72 | ### 0.1.0 [@AbnerZheng](https://github.com/AbnerZheng)
73 | - Implemented formatting feature.
74 | - Updated grammar (quick fix before Mercury) [@tgrospic](https://github.com/tgrospic).
75 |
76 | ### 0.0.4 [@AbnerZheng](https://github.com/AbnerZheng)
77 | - Implemented folding feature.
78 | - Added initial tests.
79 |
80 | ### 0.0.3
81 | - Syntax: Contracts as processes (recursive).
82 | - Syntax: Fix arithmetic operators.
83 | - New file icon.
84 |
85 | ### 0.0.2
86 | - Contributing info, plugin name change.
87 |
88 | ### 0.0.1
89 | - Initial release. Syntax highlighting.
90 |
91 | ## License
92 |
93 | [The MIT License (MIT)][license]
94 |
95 | [releases]: https://github.com/tgrospic/rholang-idea/releases
96 | [rchain-coop]: https://www.rchain.coop
97 | [rho-github]: https://github.com/rchain/rchain/tree/master/rholang
98 | [rho-bnf-origin]: https://github.com/rchain/rchain/blob/1f5450e8e54b2bbce7d81206eb8d4fdd6bc96797/rholang/src/main/bnfc/rholang.cf
99 | [rho-idea-plugin]: https://plugins.jetbrains.com/plugin/9833-rholang
100 | [arch-rholang]: http://rchain-architecture.readthedocs.io/en/latest/contracts/contract-design.html#rholang-a-concurrent-language
101 | [arch-namespace-logic]: http://rchain-architecture.readthedocs.io/en/latest/contracts/namespaces.html#namespace-logic
102 | [tuplespaces-to-picalculus]: http://mobile-process-calculi-for-programming-the-new-blockchain.readthedocs.io/en/latest/actors-tuples-and-pi.html#from-tuplespaces-to-calculus
103 |
104 | [idea-dev-setup]: http://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/prerequisites.html
105 | [idea-gen-parser]: http://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/grammar_and_parser.html#generate-a-parser
106 | [idea-gen-lexer]: http://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/lexer_and_parser_definition.html#generate-a-lexer-class
107 | [idea-deploy]: https://www.jetbrains.com/help/idea/preparing-plugins-for-publishing.html
108 | [idea-install-from-disk]: https://www.jetbrains.com/help/idea/installing-a-plugin-from-the-disk.html
109 | [idea-completion]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/completion_contributor.html
110 | [idea-reference]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/reference_contributor.html
111 | [idea-plugin-actions]: https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html
112 | [idea-test-guide]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/writing_tests_for_plugins.html
113 | [editor-config]: http://editorconfig.org
114 |
115 | [beta-badge]: https://cdn.rawgit.com/tgrospic/rholang-idea/master/docs/beta-0.1.0.svg
116 | [license]: https://github.com/tgrospic/rholang-idea/blob/master/LICENSE
117 |
--------------------------------------------------------------------------------
/src/coop/rchain/lang/Rho.bnf:
--------------------------------------------------------------------------------
1 | {
2 | parserClass="coop.rchain.lang.RhoParser"
3 |
4 | extends="com.intellij.extapi.psi.ASTWrapperPsiElement"
5 |
6 | psiClassPrefix="Rho"
7 | psiImplClassSuffix="Impl"
8 | psiPackage="coop.rchain.lang.psi"
9 | psiImplPackage="coop.rchain.lang.psi.impl"
10 |
11 | elementTypeHolderClass="coop.rchain.lang.psi.RhoTypes"
12 | elementTypeClass="coop.rchain.lang.psi.RhoElementType"
13 | tokenTypeClass="coop.rchain.lang.psi.RhoTokenType"
14 |
15 | tokens = [
16 | CONTRACT = "contract"
17 | MATCH = "match"
18 | FOR = "for"
19 | NEW = "new"
20 | SELECT = "select"
21 | IF = "if"
22 | ELSE = "else"
23 | IN = "in"
24 | FALSE = "false"
25 | TRUE = "true"
26 | NIL = "Nil"
27 |
28 | FAT_ARROW = "=>"
29 | THIN_ARROW = "->"
30 | DOT = "."
31 |
32 | BITWISE_AND = "&"
33 | BITWISE_OR = "|"
34 | BITWISE_XOR = "^"
35 |
36 | TRIPLE_DOT = "..."
37 | DOUBLE_DOT = ".."
38 | DOUBLE_COLON = "::"
39 | COLON = ":"
40 |
41 | PLUS = "+"
42 | MINUS = "-"
43 | MULTIPLY = "*"
44 | DIVIDE = "/"
45 | REMAINDER = "%"
46 |
47 | ASSIGN_LEFT_SHIFT = "<<="
48 | ASSIGN_RIGHT_SHIFT = ">>="
49 | EQUAL = "=="
50 | ASSIGN = "="
51 | NOT_EQUAL = "!="
52 | LESS_THAN_OR_EQUAL = "<="
53 | LESS_THAN = "<"
54 | GREATER_THAN_OR_EQUAL = ">="
55 | GREATER_THAN = ">"
56 |
57 | NOT = "!"
58 | BOX = "~"
59 | AT = "@"
60 | SINGLE_QUOTE = "'"
61 | DOLLAR = "$"
62 |
63 | HASH = "#"
64 | OPEN_SQUARE_BRACKET = "["
65 | CLOSE_SQUARE_BRACKET = "]"
66 | OPEN_PAREN = "("
67 | CLOSE_PAREN = ")"
68 | OPEN_BRACE = "{"
69 | CLOSE_BRACE = "}"
70 | COMMA = ","
71 | SEMICOLON = ";"
72 | UNDERSCORE = "_"
73 |
74 |
75 | space='regexp:\s+'
76 | line_comment='regexp://.*'
77 | block_comment="regexp:/\*(.|\n)*\*/"
78 |
79 | Integer='regexp:\d+(\.\d*)?'
80 | ID_NAME="regexp:([a-zA-Z'][a-zA-Z_0-9']*)|([_a-zA-Z0-9']+)"
81 | StringLit="regexp:('([^'\\]|\\.)*'|\"([^\"\\]|\\.)*\")"
82 |
83 | // todo-abner url regexp
84 | URI = "regexp:`([^`\\]|\\[`\\])*`"
85 | ]
86 |
87 | // psiImplUtilClass="coop.rchain.psi.impl.RhoPsiImplUtil"
88 | // consumeTokenMethod("Proc.*|Proc")="consumeTokenFast"
89 |
90 | // extends(".*Quantity")=Quantity
91 | }
92 |
93 | RootProc ::= Proc
94 | Proc ::= Proc_ (COMMA Proc_)*
95 | private Proc_ ::= Proc1 Proc__
96 | private Proc__ ::= ["|" Proc1 Proc__]
97 |
98 | private Proc16 ::= Ground | Collection | ProcVar | "Nil" | SimpleType | ProcBlock
99 | private Proc15 ::= "~" Proc15 | Proc16
100 | private Proc14 ::= Proc15 Proc14_
101 | private Proc14_ ::= ["/\\" Proc15 Proc14_]
102 | private Proc13 ::= Proc14 Proc13_
103 | private Proc13_ ::= ["\\/" Proc14 Proc13_ | VarRefKind Var Proc13_]
104 | private Proc12 ::= "*" RhoName | Proc13
105 | private Proc11 ::= Proc12 Proc11_ | OPEN_PAREN Proc4 CLOSE_PAREN Proc11_
106 | private private Proc11_ ::= [DOT Var ProcParenOption Proc11_]
107 |
108 | private Proc10 ::= NOT Proc10 | "-" Proc10 | Proc11
109 |
110 | private Proc9 ::= Proc10 Proc9_
111 | private Proc9_ ::= [("*" | "/" | "%%") Proc10 Proc9_]
112 |
113 | private Proc8 ::= Proc9 Proc8_
114 | private Proc8_ ::= [("+" | "-" | "++" | "--") Proc9 Proc8_]
115 |
116 | private Proc7 ::= Proc8 Proc7_
117 | private Proc7_ ::= [("<" | "<=" | ">" | ">=" | "matches") Proc8 Proc7_]
118 |
119 | private Proc6 ::= Proc7 Proc6_
120 | private Proc6_ ::= [("==" | "!=") Proc7 Proc6_]
121 |
122 | private Proc5 ::= Proc6 Proc5_
123 | private Proc5_ ::= ["and" Proc6 Proc5_]
124 |
125 | private Proc4 ::= Proc5 Proc4_
126 | private Proc4_ ::= ["or" Proc5 Proc4_]
127 | Proc3 ::= RhoName Send ProcParenOption | Proc4
128 | private Proc2 ::= PContr | PInput | PChoice | PMatch | PBundle | Proc3
129 | private Proc1 ::= PIfElse | PIf | PNew | Proc2
130 |
131 | PContr ::= CONTRACT RhoName OPEN_PAREN RhoName? NameRemainder CLOSE_PAREN ASSIGN ProcBlock
132 | PInput ::= FOR OPEN_PAREN Receipt CLOSE_PAREN ProcBlock
133 | PChoice ::= SELECT OPEN_BRACE Branch? CLOSE_BRACE
134 | PBundle ::= Bundle ProcBlock
135 | PMatch ::= MATCH Proc4 CaseBlock
136 |
137 | CaseBlock ::= OPEN_BRACE [Case] CLOSE_BRACE
138 |
139 | PIfElse ::= IF OPEN_PAREN Proc CLOSE_PAREN Proc2 ELSE Proc1
140 | PIf ::= IF OPEN_PAREN Proc CLOSE_PAREN Proc2
141 | PNew ::= NEW NameDecl? IN Proc1
142 |
143 |
144 | ProcBlock ::= OPEN_BRACE Proc CLOSE_BRACE
145 | ProcBlockOption ::= OPEN_BRACE [Proc] CLOSE_BRACE
146 | ProcParenOption ::= "(" [Proc] ")"
147 |
148 | // Process variables
149 | ProcVar ::= "_" | Var
150 |
151 | Var ::= ID_NAME
152 |
153 | // This is needed for differ from Name and ProcessVar
154 | NameVar ::= Var {
155 | implements = [ "coop.rchain.lang.psi.RhoNamedElement" ]
156 | mixin = "coop.rchain.lang.psi.RhoNamedElementImpl"
157 | }
158 |
159 | // Names
160 | Name_ ::= "_" | NameVar | AT Proc12 {
161 | implements = [ "coop.rchain.lang.psi.RhoNamedElement" ]
162 | mixin = "coop.rchain.lang.psi.RhoNamedElementImpl"
163 | }
164 | RhoName ::= Name_ ("," Name_)*
165 |
166 | // Bundle
167 | Bundle ::= "bundle+" | "bundle-" | "bundle0" | "bundle"
168 |
169 | // Receipt
170 | Receipt ::= ReceiptLinearImpl
171 |
172 | ReceiptLinearImpl ::= [LinearBind]
173 |
174 | private LinearBind_ ::= [RhoName] NameRemainder ("<-"|"<=") RhoName
175 |
176 | LinearBind ::= LinearBind_ (";" LinearBind_)*
177 |
178 | // Types of Send
179 | Send ::= "!" || "!!"
180 |
181 | // select branches
182 | private Branch_ ::= ReceiptLinearImpl "=>" Proc3
183 | Branch ::= Branch_+
184 |
185 | // Match Cases
186 | Case_ ::= Proc13 "=>" Proc3
187 | Case ::= Case_+
188 |
189 | // Name Declarations
190 | // Eventually will have IOPairs.
191 | NameDecl ::= NameDecl_ ("," NameDecl_)*
192 | NameDecl_ ::= NameVar OPEN_PAREN URI CLOSE_PAREN | NameVar
193 |
194 | // Booleans:
195 | Bool ::= TRUE | FALSE
196 |
197 | // Ground
198 | Ground ::= Bool | Integer | StringLit | URI
199 |
200 | // Collections:
201 | private CollectList ::= OPEN_SQUARE_BRACKET [Proc] ProcRemainder CLOSE_SQUARE_BRACKET
202 | private CollectTuple ::= Tuple
203 | private CollectSet ::= "Set" "(" [Proc] ")"
204 | private CollectMap ::= "{" [KeyValuePair] "}"
205 |
206 | // important: we use Proc_ here, because if we use Proc, they will all consume COMMA
207 | private KeyValuePair_ ::= Proc COLON Proc_
208 | KeyValuePair ::= KeyValuePair_ (COMMA KeyValuePair_)*
209 | private Tuple ::= OPEN_PAREN Proc ",)" | OPEN_PAREN Proc COMMA [Proc] CLOSE_PAREN
210 |
211 |
212 |
213 | Collection ::= CollectList | CollectTuple | CollectMap | CollectSet
214 |
215 |
216 | // Remainders:
217 | ProcRemainder ::= (TRIPLE_DOT Var)?
218 |
219 | NameRemainder ::= (TRIPLE_DOT AT Var)?
220 |
221 |
222 | VarRefKind ::= "=" | "=" "*"
223 |
224 | SimpleType ::= "Bool" | "Int" | "String" | "Url" | "ByteArray"
225 |
--------------------------------------------------------------------------------
/testData/lexer/token.rho:
--------------------------------------------------------------------------------
1 | // A token contract that implements the ERC20 standard.
2 | // This contract demonstrates the creation of a token,
3 | // the transferring of tokens, the querying of a balance,
4 | // and the printing of the balance query result.
5 |
6 | new token in {
7 | contract token (message_sender, total_supply, return_channel) = {
8 | new allowed_channel, balances_channel, owner_channel in {
9 | allowed_channel!(Map()) |
10 | owner_channel!(message_sender) |
11 | balances_channel!(Map()) |
12 | for (balances <- balances_channel) {
13 | balances_channel!( balances.insert(message_sender, total_supply) )
14 | } |
15 | new transfer, transfer_from, approve, balance_of, allowance, contract_owner in {
16 | contract transfer(message_sender, to, amount, rtn) = {
17 | for (balances <- balances_channel) {
18 | new x, y in {
19 | x!(balances.getOrElse(message_sender, 0)) |
20 | y!(balances.getOrElse(to, 0)) |
21 | for (balance_of_sender <- x
22 | ; balance_of_receiver <- y) {
23 | // Preconditions to check before the transfer goes through
24 | match [
25 | balance_of_sender >= amount,
26 | amount > 0,
27 | balance_of_receiver + amount > balance_of_receiver
28 | ] {
29 | [true, true, true] => {
30 | balances_channel!(
31 | (balances
32 | .insert(message_sender, balance_of_sender - amount))
33 | .insert(to, balance_of_receiver+amount)
34 | ) |
35 | rtn!(true)
36 | }
37 | _ => {
38 | balances_channel!(balances) |
39 | rtn!(false)
40 | }
41 | }
42 | }
43 | }
44 | }
45 | } |
46 | // Same as the transfer contract but allows for the sender to be different from
47 | // the person calling the transfer_from contract
48 | contract transfer_from(message_sender, from, to, amount, rtn) = {
49 | for (balances <- balances_channel
50 | ; allowed <- allowed_channel) {
51 | new x, y, z in {
52 | x!(balances.getOrElse(from, 0)) |
53 | y!(allowed.getOrElse(from, message_sender, 0)) |
54 | z!(balances.getOrElse(to, 0)) |
55 | for ( balance_of_sender <- x
56 | ; sender_allowed <- y
57 | ; balance_of_receiver <- z ) {
58 | match [
59 | balance_of_sender >= amount,
60 | sender_allowed >= amount,
61 | amount > 0,
62 | balance_of_receiver + amount > balance_of_receiver
63 | ] {
64 | [true, true, true, true] => {
65 | balances_channel!(
66 | (balances
67 | .insert(from, balance_of_sender - amount))
68 | .insert(to, balance_of_receiver + amount)
69 | ) |
70 | allowed_channel!(
71 | allowed.insert(from, message_sender, sender_allowed - amount)
72 | ) |
73 | rtn!(true)
74 | }
75 | _ => {
76 | balances_channel!(balances) |
77 | allowed_channel!(allowed) |
78 | rtn!(false)
79 | }
80 | }
81 | }
82 | }
83 | }
84 | } |
85 | // This is the way an address can pre-approve (delegate) the transfer of
86 | // a certain amount of tokens to some other address. This allows for
87 | // that other address, through the use of the transfer_from function,
88 | // to send up to that amount of tokens.
89 | contract approve(message_sender, spender, amount, rtn) = {
90 | for (allowed <- allowed_channel) {
91 | allowed_channel!(allowed.insert(message_sender,spender,amount)) |
92 | rtn!(true)
93 | }
94 | } |
95 | contract balance_of(owner, rtn) = {
96 | for (balances <- balances_channel) {
97 | rtn!(balances.getOrElse(owner, 0)) |
98 | balances_channel!(balances)
99 | }
100 | } |
101 | contract allowance(owner, spender, rtn) = {
102 | for (allowed <- allowed_channel) {
103 | allowed_channel!(allowed) |
104 | rtn!(allowed.getOrElse(owner,spender,0))
105 | }
106 | } |
107 | contract contract_owner(rtn) = {
108 | for (owner <- owner_channel) {
109 | owner_channel!(owner) |
110 | rtn!(owner)
111 | }
112 | } |
113 | return_channel!(
114 | Map().insertMany("transfer", transfer, "transfer_from", transfer_from,
115 | "approve", approve, "balance_of", balance_of, "allowance", allowance,
116 | "contract_owner", contract_owner))
117 | // TODO: Eventually just insert with compiler
118 | }
119 | }
120 | } |
121 | new rtn, me, they in {
122 | token!(me, 100, rtn) |
123 | for (token_contract <- rtn) {
124 | new unused_rtn, balance_of_rtn in {
125 | @token_contract.get("transfer")!(me, they, 50, unused_rtn) |
126 | @token_contract.get("balance_of")!(they, balance_of_rtn) |
127 | for (they_balance <- balance_of_rtn) {
128 | they_balance.display("\n")
129 | }
130 | }
131 | }
132 | } |
133 | new rtn2, me2, they2 in {
134 | token!(me2, 1000, rtn2) |
135 | for (token_contract2 <- rtn2) {
136 | new unused_rtn2, balance_of_rtn2 in {
137 | @token_contract2.get("transfer")!(me2, they2, 500, unused_rtn2) |
138 | @token_contract2.get("balance_of")!(they2, balance_of_rtn2) |
139 | for (they_balance2 <- balance_of_rtn2) {
140 | they_balance2.display("\n")
141 | }
142 | }
143 | }
144 | }
145 | // Once we have a registry, we can do registry_channel!(token) to save the contract there
146 | }
147 |
--------------------------------------------------------------------------------
/testData/parser/token.txt:
--------------------------------------------------------------------------------
1 | Rholang File
2 | RhoPNewImpl(P_NEW)
3 | PsiElement(new)('new')
4 | PsiWhiteSpace(' ')
5 | RhoNameDeclImpl(NAME_DECL)
6 | RhoVarImpl(VAR)
7 | PsiElement(ID_NAME)('testResult')
8 | PsiElement(comma)(',')
9 | PsiWhiteSpace(' ')
10 | RhoVarImpl(VAR)
11 | PsiElement(ID_NAME)('philosopher1')
12 | PsiElement(comma)(',')
13 | PsiWhiteSpace(' ')
14 | RhoVarImpl(VAR)
15 | PsiElement(ID_NAME)('philosopher2')
16 | PsiWhiteSpace(' ')
17 | PsiElement(in)('in')
18 | PsiWhiteSpace(' ')
19 | RhoProc3Impl(PROC_3)
20 | RhoProcBlockImpl(PROC_BLOCK)
21 | PsiElement({)('{')
22 | PsiWhiteSpace('\n ')
23 | RhoPNewImpl(P_NEW)
24 | PsiElement(new)('new')
25 | PsiWhiteSpace(' ')
26 | RhoNameDeclImpl(NAME_DECL)
27 | RhoVarImpl(VAR)
28 | PsiElement(ID_NAME)('north')
29 | PsiElement(comma)(',')
30 | PsiWhiteSpace(' ')
31 | RhoVarImpl(VAR)
32 | PsiElement(ID_NAME)('south')
33 | PsiElement(comma)(',')
34 | PsiWhiteSpace(' ')
35 | RhoVarImpl(VAR)
36 | PsiElement(ID_NAME)('knife')
37 | PsiElement(comma)(',')
38 | PsiWhiteSpace(' ')
39 | RhoVarImpl(VAR)
40 | PsiElement(ID_NAME)('spoon')
41 | PsiWhiteSpace(' ')
42 | PsiElement(in)('in')
43 | PsiWhiteSpace(' ')
44 | RhoProc3Impl(PROC_3)
45 | RhoProcBlockImpl(PROC_BLOCK)
46 | PsiElement({)('{')
47 | PsiWhiteSpace('\n ')
48 | RhoProc3Impl(PROC_3)
49 | RhoRhoNameImpl(RHO_NAME)
50 | RhoName_Impl(NAME_)
51 | RhoVarImpl(VAR)
52 | PsiElement(ID_NAME)('north')
53 | RhoSendImpl(SEND)
54 | PsiElement(!)('!')
55 | RhoProcParenOptionImpl(PROC_PAREN_OPTION)
56 | PsiElement(()('(')
57 | RhoProc3Impl(PROC_3)
58 | PsiElement(*)('*')
59 | RhoRhoNameImpl(RHO_NAME)
60 | RhoName_Impl(NAME_)
61 | RhoVarImpl(VAR)
62 | PsiElement(ID_NAME)('knife')
63 | PsiElement())(')')
64 | PsiWhiteSpace(' ')
65 | PsiElement(|)('|')
66 | PsiWhiteSpace('\n ')
67 | RhoProc3Impl(PROC_3)
68 | RhoRhoNameImpl(RHO_NAME)
69 | RhoName_Impl(NAME_)
70 | RhoVarImpl(VAR)
71 | PsiElement(ID_NAME)('south')
72 | RhoSendImpl(SEND)
73 | PsiElement(!)('!')
74 | RhoProcParenOptionImpl(PROC_PAREN_OPTION)
75 | PsiElement(()('(')
76 | RhoProc3Impl(PROC_3)
77 | PsiElement(*)('*')
78 | RhoRhoNameImpl(RHO_NAME)
79 | RhoName_Impl(NAME_)
80 | RhoVarImpl(VAR)
81 | PsiElement(ID_NAME)('spoon')
82 | PsiElement())(')')
83 | PsiWhiteSpace(' ')
84 | PsiElement(|)('|')
85 | PsiWhiteSpace('\n ')
86 | RhoPInputImpl(P_INPUT)
87 | PsiElement(for)('for')
88 | PsiWhiteSpace(' ')
89 | PsiElement(()('(')
90 | RhoReceiptImpl(RECEIPT)
91 | RhoReceiptLinearImplImpl(RECEIPT_LINEAR_IMPL)
92 | RhoLinearBindImpl(LINEAR_BIND)
93 | RhoRhoNameImpl(RHO_NAME)
94 | RhoName_Impl(NAME_)
95 | PsiElement(@)('@')
96 | RhoProcVarImpl(PROC_VAR)
97 | RhoVarImpl(VAR)
98 | PsiElement(ID_NAME)('knf')
99 | PsiWhiteSpace(' ')
100 | RhoNameRemainderImpl(NAME_REMAINDER)
101 |
102 | PsiElement(<)('<')
103 | PsiElement(-)('-')
104 | PsiWhiteSpace(' ')
105 | RhoRhoNameImpl(RHO_NAME)
106 | RhoName_Impl(NAME_)
107 | RhoVarImpl(VAR)
108 | PsiElement(ID_NAME)('north')
109 | PsiElement(;)(';')
110 | PsiWhiteSpace(' ')
111 | RhoRhoNameImpl(RHO_NAME)
112 | RhoName_Impl(NAME_)
113 | PsiElement(@)('@')
114 | RhoProcVarImpl(PROC_VAR)
115 | RhoVarImpl(VAR)
116 | PsiElement(ID_NAME)('spn')
117 | PsiWhiteSpace(' ')
118 | RhoNameRemainderImpl(NAME_REMAINDER)
119 |
120 | PsiElement(<)('<')
121 | PsiElement(-)('-')
122 | PsiWhiteSpace(' ')
123 | RhoRhoNameImpl(RHO_NAME)
124 | RhoName_Impl(NAME_)
125 | RhoVarImpl(VAR)
126 | PsiElement(ID_NAME)('south')
127 | PsiElement())(')')
128 | PsiWhiteSpace(' ')
129 | PsiElement({)('{')
130 | PsiWhiteSpace('\n ')
131 | RhoProc3Impl(PROC_3)
132 | RhoRhoNameImpl(RHO_NAME)
133 | RhoName_Impl(NAME_)
134 | RhoVarImpl(VAR)
135 | PsiElement(ID_NAME)('philosopher1')
136 | RhoSendImpl(SEND)
137 | PsiElement(!)('!')
138 | RhoProcParenOptionImpl(PROC_PAREN_OPTION)
139 | PsiElement(()('(')
140 | RhoProc3Impl(PROC_3)
141 | RhoGroundImpl(GROUND)
142 | RhoBoolImpl(BOOL)
143 | PsiElement(true)('true')
144 | PsiElement())(')')
145 | PsiWhiteSpace(' ')
146 | PsiElement(|)('|')
147 | PsiWhiteSpace('\n ')
148 | RhoProc3Impl(PROC_3)
149 | RhoRhoNameImpl(RHO_NAME)
150 | RhoName_Impl(NAME_)
151 | RhoVarImpl(VAR)
152 | PsiElement(ID_NAME)('north')
153 | RhoSendImpl(SEND)
154 | PsiElement(!)('!')
155 | RhoProcParenOptionImpl(PROC_PAREN_OPTION)
156 | PsiElement(()('(')
157 | RhoProc3Impl(PROC_3)
158 | RhoProcVarImpl(PROC_VAR)
159 | RhoVarImpl(VAR)
160 | PsiElement(ID_NAME)('knf')
161 | PsiElement())(')')
162 | PsiWhiteSpace(' ')
163 | PsiElement(|)('|')
164 | PsiWhiteSpace('\n ')
165 | RhoProc3Impl(PROC_3)
166 | RhoRhoNameImpl(RHO_NAME)
167 | RhoName_Impl(NAME_)
168 | RhoVarImpl(VAR)
169 | PsiElement(ID_NAME)('south')
170 | RhoSendImpl(SEND)
171 | PsiElement(!)('!')
172 | RhoProcParenOptionImpl(PROC_PAREN_OPTION)
173 | PsiElement(()('(')
174 | RhoProc3Impl(PROC_3)
175 | RhoProcVarImpl(PROC_VAR)
176 | RhoVarImpl(VAR)
177 | PsiElement(ID_NAME)('spn')
178 | PsiElement())(')')
179 | PsiWhiteSpace('\n ')
180 | PsiElement(})('}')
181 | PsiWhiteSpace(' ')
182 | PsiElement(|)('|')
183 | PsiWhiteSpace('\n ')
184 | RhoPInputImpl(P_INPUT)
185 | PsiElement(for)('for')
186 | PsiWhiteSpace(' ')
187 | PsiElement(()('(')
188 | RhoReceiptImpl(RECEIPT)
189 | RhoReceiptLinearImplImpl(RECEIPT_LINEAR_IMPL)
190 | RhoLinearBindImpl(LINEAR_BIND)
191 | RhoRhoNameImpl(RHO_NAME)
192 | RhoName_Impl(NAME_)
193 | PsiElement(@)('@')
194 | RhoProcVarImpl(PROC_VAR)
195 | RhoVarImpl(VAR)
196 | PsiElement(ID_NAME)('spn')
197 | PsiWhiteSpace(' ')
198 | RhoNameRemainderImpl(NAME_REMAINDER)
199 |
200 | PsiElement(<)('<')
201 | PsiElement(-)('-')
202 | PsiWhiteSpace(' ')
203 | RhoRhoNameImpl(RHO_NAME)
204 | RhoName_Impl(NAME_)
205 | RhoVarImpl(VAR)
206 | PsiElement(ID_NAME)('south')
207 | PsiElement(;)(';')
208 | PsiWhiteSpace(' ')
209 | RhoRhoNameImpl(RHO_NAME)
210 | RhoName_Impl(NAME_)
211 | PsiElement(@)('@')
212 | RhoProcVarImpl(PROC_VAR)
213 | RhoVarImpl(VAR)
214 | PsiElement(ID_NAME)('knf')
215 | PsiWhiteSpace(' ')
216 | RhoNameRemainderImpl(NAME_REMAINDER)
217 |
218 | PsiElement(<)('<')
219 | PsiElement(-)('-')
220 | PsiWhiteSpace(' ')
221 | RhoRhoNameImpl(RHO_NAME)
222 | RhoName_Impl(NAME_)
223 | RhoVarImpl(VAR)
224 | PsiElement(ID_NAME)('north')
225 | PsiElement())(')')
226 | PsiWhiteSpace(' ')
227 | PsiElement({)('{')
228 | PsiWhiteSpace('\n ')
229 | RhoProc3Impl(PROC_3)
230 | RhoRhoNameImpl(RHO_NAME)
231 | RhoName_Impl(NAME_)
232 | RhoVarImpl(VAR)
233 | PsiElement(ID_NAME)('philosopher2')
234 | RhoSendImpl(SEND)
235 | PsiElement(!)('!')
236 | RhoProcParenOptionImpl(PROC_PAREN_OPTION)
237 | PsiElement(()('(')
238 | RhoProc3Impl(PROC_3)
239 | RhoGroundImpl(GROUND)
240 | RhoBoolImpl(BOOL)
241 | PsiElement(true)('true')
242 | PsiElement())(')')
243 | PsiWhiteSpace(' ')
244 | PsiElement(|)('|')
245 | PsiWhiteSpace('\n ')
246 | RhoProc3Impl(PROC_3)
247 | RhoRhoNameImpl(RHO_NAME)
248 | RhoName_Impl(NAME_)
249 | RhoVarImpl(VAR)
250 | PsiElement(ID_NAME)('north')
251 | RhoSendImpl(SEND)
252 | PsiElement(!)('!')
253 | RhoProcParenOptionImpl(PROC_PAREN_OPTION)
254 | PsiElement(()('(')
255 | RhoProc3Impl(PROC_3)
256 | RhoProcVarImpl(PROC_VAR)
257 | RhoVarImpl(VAR)
258 | PsiElement(ID_NAME)('knf')
259 | PsiElement())(')')
260 | PsiWhiteSpace(' ')
261 | PsiElement(|)('|')
262 | PsiWhiteSpace('\n ')
263 | RhoProc3Impl(PROC_3)
264 | RhoRhoNameImpl(RHO_NAME)
265 | RhoName_Impl(NAME_)
266 | RhoVarImpl(VAR)
267 | PsiElement(ID_NAME)('south')
268 | RhoSendImpl(SEND)
269 | PsiElement(!)('!')
270 | RhoProcParenOptionImpl(PROC_PAREN_OPTION)
271 | PsiElement(()('(')
272 | RhoProc3Impl(PROC_3)
273 | RhoProcVarImpl(PROC_VAR)
274 | RhoVarImpl(VAR)
275 | PsiElement(ID_NAME)('spn')
276 | PsiElement())(')')
277 | PsiWhiteSpace('\n ')
278 | PsiElement(})('}')
279 | PsiWhiteSpace('\n ')
280 | PsiElement(})('}')
281 | PsiWhiteSpace(' ')
282 | PsiElement(|)('|')
283 | PsiWhiteSpace('\n ')
284 | RhoPInputImpl(P_INPUT)
285 | PsiElement(for)('for')
286 | PsiElement(()('(')
287 | RhoReceiptImpl(RECEIPT)
288 | RhoReceiptLinearImplImpl(RECEIPT_LINEAR_IMPL)
289 | RhoLinearBindImpl(LINEAR_BIND)
290 | RhoRhoNameImpl(RHO_NAME)
291 | RhoName_Impl(NAME_)
292 | PsiElement(_)('_')
293 | PsiWhiteSpace(' ')
294 | RhoNameRemainderImpl(NAME_REMAINDER)
295 |
296 | PsiElement(<)('<')
297 | PsiElement(-)('-')
298 | PsiWhiteSpace(' ')
299 | RhoRhoNameImpl(RHO_NAME)
300 | RhoName_Impl(NAME_)
301 | RhoVarImpl(VAR)
302 | PsiElement(ID_NAME)('philosopher1')
303 | PsiElement(;)(';')
304 | PsiWhiteSpace(' ')
305 | RhoRhoNameImpl(RHO_NAME)
306 | RhoName_Impl(NAME_)
307 | PsiElement(_)('_')
308 | PsiWhiteSpace(' ')
309 | RhoNameRemainderImpl(NAME_REMAINDER)
310 |
311 | PsiElement(<)('<')
312 | PsiElement(-)('-')
313 | PsiWhiteSpace(' ')
314 | RhoRhoNameImpl(RHO_NAME)
315 | RhoName_Impl(NAME_)
316 | RhoVarImpl(VAR)
317 | PsiElement(ID_NAME)('philosopher2')
318 | PsiElement())(')')
319 | PsiWhiteSpace(' ')
320 | PsiElement({)('{')
321 | PsiWhiteSpace('\n ')
322 | RhoProc3Impl(PROC_3)
323 | RhoRhoNameImpl(RHO_NAME)
324 | RhoName_Impl(NAME_)
325 | RhoVarImpl(VAR)
326 | PsiElement(ID_NAME)('testResult')
327 | RhoSendImpl(SEND)
328 | PsiElement(!)('!')
329 | RhoProcParenOptionImpl(PROC_PAREN_OPTION)
330 | PsiElement(()('(')
331 | RhoProc3Impl(PROC_3)
332 | RhoGroundImpl(GROUND)
333 | RhoBoolImpl(BOOL)
334 | PsiElement(true)('true')
335 | PsiElement())(')')
336 | PsiWhiteSpace('\n ')
337 | PsiElement(})('}')
338 | PsiWhiteSpace('\n')
339 | PsiElement(})('}')
340 |
--------------------------------------------------------------------------------
/testData/lexer/token.txt:
--------------------------------------------------------------------------------
1 | line_comment ('// A token contract that implements the ERC20 standard.')
2 | WHITE_SPACE ('\n')
3 | line_comment ('// This contract demonstrates the creation of a token,')
4 | WHITE_SPACE ('\n')
5 | line_comment ('// the transferring of tokens, the querying of a balance,')
6 | WHITE_SPACE ('\n')
7 | line_comment ('// and the printing of the balance query result.')
8 | WHITE_SPACE ('\n\n')
9 | new ('new')
10 | WHITE_SPACE (' ')
11 | ID_NAME ('token')
12 | WHITE_SPACE (' ')
13 | in ('in')
14 | WHITE_SPACE (' ')
15 | { ('{')
16 | WHITE_SPACE ('\n ')
17 | contract ('contract')
18 | WHITE_SPACE (' ')
19 | ID_NAME ('token')
20 | WHITE_SPACE (' ')
21 | ( ('(')
22 | ID_NAME ('message_sender')
23 | comma (',')
24 | WHITE_SPACE (' ')
25 | ID_NAME ('total_supply')
26 | comma (',')
27 | WHITE_SPACE (' ')
28 | ID_NAME ('return_channel')
29 | ) (')')
30 | WHITE_SPACE (' ')
31 | = ('=')
32 | WHITE_SPACE (' ')
33 | { ('{')
34 | WHITE_SPACE ('\n ')
35 | new ('new')
36 | WHITE_SPACE (' ')
37 | ID_NAME ('allowed_channel')
38 | comma (',')
39 | WHITE_SPACE (' ')
40 | ID_NAME ('balances_channel')
41 | comma (',')
42 | WHITE_SPACE (' ')
43 | ID_NAME ('owner_channel')
44 | WHITE_SPACE (' ')
45 | in ('in')
46 | WHITE_SPACE (' ')
47 | { ('{')
48 | WHITE_SPACE ('\n ')
49 | ID_NAME ('allowed_channel')
50 | ! ('!')
51 | ( ('(')
52 | ID_NAME ('Map')
53 | ( ('(')
54 | ) (')')
55 | ) (')')
56 | WHITE_SPACE (' ')
57 | | ('|')
58 | WHITE_SPACE ('\n ')
59 | ID_NAME ('owner_channel')
60 | ! ('!')
61 | ( ('(')
62 | ID_NAME ('message_sender')
63 | ) (')')
64 | WHITE_SPACE (' ')
65 | | ('|')
66 | WHITE_SPACE ('\n ')
67 | ID_NAME ('balances_channel')
68 | ! ('!')
69 | ( ('(')
70 | ID_NAME ('Map')
71 | ( ('(')
72 | ) (')')
73 | ) (')')
74 | WHITE_SPACE (' ')
75 | | ('|')
76 | WHITE_SPACE ('\n ')
77 | for ('for')
78 | WHITE_SPACE (' ')
79 | ( ('(')
80 | ID_NAME ('balances')
81 | WHITE_SPACE (' ')
82 | < ('<')
83 | - ('-')
84 | WHITE_SPACE (' ')
85 | ID_NAME ('balances_channel')
86 | ) (')')
87 | WHITE_SPACE (' ')
88 | { ('{')
89 | WHITE_SPACE ('\n ')
90 | ID_NAME ('balances_channel')
91 | ! ('!')
92 | ( ('(')
93 | WHITE_SPACE (' ')
94 | ID_NAME ('balances')
95 | . ('.')
96 | ID_NAME ('insert')
97 | ( ('(')
98 | ID_NAME ('message_sender')
99 | comma (',')
100 | WHITE_SPACE (' ')
101 | ID_NAME ('total_supply')
102 | ) (')')
103 | WHITE_SPACE (' ')
104 | ) (')')
105 | WHITE_SPACE ('\n ')
106 | } ('}')
107 | WHITE_SPACE (' ')
108 | | ('|')
109 | WHITE_SPACE ('\n ')
110 | new ('new')
111 | WHITE_SPACE (' ')
112 | ID_NAME ('transfer')
113 | comma (',')
114 | WHITE_SPACE (' ')
115 | ID_NAME ('transfer_from')
116 | comma (',')
117 | WHITE_SPACE (' ')
118 | ID_NAME ('approve')
119 | comma (',')
120 | WHITE_SPACE (' ')
121 | ID_NAME ('balance_of')
122 | comma (',')
123 | WHITE_SPACE (' ')
124 | ID_NAME ('allowance')
125 | comma (',')
126 | WHITE_SPACE (' ')
127 | ID_NAME ('contract_owner')
128 | WHITE_SPACE (' ')
129 | in ('in')
130 | WHITE_SPACE (' ')
131 | { ('{')
132 | WHITE_SPACE ('\n ')
133 | contract ('contract')
134 | WHITE_SPACE (' ')
135 | ID_NAME ('transfer')
136 | ( ('(')
137 | ID_NAME ('message_sender')
138 | comma (',')
139 | WHITE_SPACE (' ')
140 | ID_NAME ('to')
141 | comma (',')
142 | WHITE_SPACE (' ')
143 | ID_NAME ('amount')
144 | comma (',')
145 | WHITE_SPACE (' ')
146 | ID_NAME ('rtn')
147 | ) (')')
148 | WHITE_SPACE (' ')
149 | = ('=')
150 | WHITE_SPACE (' ')
151 | { ('{')
152 | WHITE_SPACE ('\n ')
153 | for ('for')
154 | WHITE_SPACE (' ')
155 | ( ('(')
156 | ID_NAME ('balances')
157 | WHITE_SPACE (' ')
158 | < ('<')
159 | - ('-')
160 | WHITE_SPACE (' ')
161 | ID_NAME ('balances_channel')
162 | ) (')')
163 | WHITE_SPACE (' ')
164 | { ('{')
165 | WHITE_SPACE ('\n ')
166 | new ('new')
167 | WHITE_SPACE (' ')
168 | ID_NAME ('x')
169 | comma (',')
170 | WHITE_SPACE (' ')
171 | ID_NAME ('y')
172 | WHITE_SPACE (' ')
173 | in ('in')
174 | WHITE_SPACE (' ')
175 | { ('{')
176 | WHITE_SPACE ('\n ')
177 | ID_NAME ('x')
178 | ! ('!')
179 | ( ('(')
180 | ID_NAME ('balances')
181 | . ('.')
182 | ID_NAME ('getOrElse')
183 | ( ('(')
184 | ID_NAME ('message_sender')
185 | comma (',')
186 | WHITE_SPACE (' ')
187 | Integer ('0')
188 | ) (')')
189 | ) (')')
190 | WHITE_SPACE (' ')
191 | | ('|')
192 | WHITE_SPACE ('\n ')
193 | ID_NAME ('y')
194 | ! ('!')
195 | ( ('(')
196 | ID_NAME ('balances')
197 | . ('.')
198 | ID_NAME ('getOrElse')
199 | ( ('(')
200 | ID_NAME ('to')
201 | comma (',')
202 | WHITE_SPACE (' ')
203 | Integer ('0')
204 | ) (')')
205 | ) (')')
206 | WHITE_SPACE (' ')
207 | | ('|')
208 | WHITE_SPACE ('\n ')
209 | for ('for')
210 | WHITE_SPACE (' ')
211 | ( ('(')
212 | ID_NAME ('balance_of_sender')
213 | WHITE_SPACE (' ')
214 | < ('<')
215 | - ('-')
216 | WHITE_SPACE (' ')
217 | ID_NAME ('x')
218 | WHITE_SPACE ('\n ')
219 | ; (';')
220 | WHITE_SPACE (' ')
221 | ID_NAME ('balance_of_receiver')
222 | WHITE_SPACE (' ')
223 | < ('<')
224 | - ('-')
225 | WHITE_SPACE (' ')
226 | ID_NAME ('y')
227 | ) (')')
228 | WHITE_SPACE (' ')
229 | { ('{')
230 | WHITE_SPACE ('\n ')
231 | line_comment ('// Preconditions to check before the transfer goes through')
232 | WHITE_SPACE ('\n ')
233 | match ('match')
234 | WHITE_SPACE (' ')
235 | [ ('[')
236 | WHITE_SPACE ('\n ')
237 | ID_NAME ('balance_of_sender')
238 | WHITE_SPACE (' ')
239 | >= ('>=')
240 | WHITE_SPACE (' ')
241 | ID_NAME ('amount')
242 | comma (',')
243 | WHITE_SPACE ('\n ')
244 | ID_NAME ('amount')
245 | WHITE_SPACE (' ')
246 | > ('>')
247 | WHITE_SPACE (' ')
248 | Integer ('0')
249 | comma (',')
250 | WHITE_SPACE ('\n ')
251 | ID_NAME ('balance_of_receiver')
252 | WHITE_SPACE (' ')
253 | + ('+')
254 | WHITE_SPACE (' ')
255 | ID_NAME ('amount')
256 | WHITE_SPACE (' ')
257 | > ('>')
258 | WHITE_SPACE (' ')
259 | ID_NAME ('balance_of_receiver')
260 | WHITE_SPACE ('\n ')
261 | ] (']')
262 | WHITE_SPACE (' ')
263 | { ('{')
264 | WHITE_SPACE ('\n ')
265 | [ ('[')
266 | true ('true')
267 | comma (',')
268 | WHITE_SPACE (' ')
269 | true ('true')
270 | comma (',')
271 | WHITE_SPACE (' ')
272 | true ('true')
273 | ] (']')
274 | WHITE_SPACE (' ')
275 | => ('=>')
276 | WHITE_SPACE (' ')
277 | { ('{')
278 | WHITE_SPACE ('\n ')
279 | ID_NAME ('balances_channel')
280 | ! ('!')
281 | ( ('(')
282 | WHITE_SPACE ('\n ')
283 | ( ('(')
284 | ID_NAME ('balances')
285 | WHITE_SPACE ('\n ')
286 | . ('.')
287 | ID_NAME ('insert')
288 | ( ('(')
289 | ID_NAME ('message_sender')
290 | comma (',')
291 | WHITE_SPACE (' ')
292 | ID_NAME ('balance_of_sender')
293 | WHITE_SPACE (' ')
294 | - ('-')
295 | WHITE_SPACE (' ')
296 | ID_NAME ('amount')
297 | ) (')')
298 | ) (')')
299 | WHITE_SPACE ('\n ')
300 | . ('.')
301 | ID_NAME ('insert')
302 | ( ('(')
303 | ID_NAME ('to')
304 | comma (',')
305 | WHITE_SPACE (' ')
306 | ID_NAME ('balance_of_receiver')
307 | + ('+')
308 | ID_NAME ('amount')
309 | ) (')')
310 | WHITE_SPACE ('\n ')
311 | ) (')')
312 | WHITE_SPACE (' ')
313 | | ('|')
314 | WHITE_SPACE ('\n ')
315 | ID_NAME ('rtn')
316 | ! ('!')
317 | ( ('(')
318 | true ('true')
319 | ) (')')
320 | WHITE_SPACE ('\n ')
321 | } ('}')
322 | WHITE_SPACE ('\n ')
323 | _ ('_')
324 | WHITE_SPACE (' ')
325 | => ('=>')
326 | WHITE_SPACE (' ')
327 | { ('{')
328 | WHITE_SPACE ('\n ')
329 | ID_NAME ('balances_channel')
330 | ! ('!')
331 | ( ('(')
332 | ID_NAME ('balances')
333 | ) (')')
334 | WHITE_SPACE (' ')
335 | | ('|')
336 | WHITE_SPACE ('\n ')
337 | ID_NAME ('rtn')
338 | ! ('!')
339 | ( ('(')
340 | false ('false')
341 | ) (')')
342 | WHITE_SPACE ('\n ')
343 | } ('}')
344 | WHITE_SPACE ('\n ')
345 | } ('}')
346 | WHITE_SPACE ('\n ')
347 | } ('}')
348 | WHITE_SPACE ('\n ')
349 | } ('}')
350 | WHITE_SPACE ('\n ')
351 | } ('}')
352 | WHITE_SPACE ('\n ')
353 | } ('}')
354 | WHITE_SPACE (' ')
355 | | ('|')
356 | WHITE_SPACE ('\n ')
357 | line_comment ('// Same as the transfer contract but allows for the sender to be different from')
358 | WHITE_SPACE ('\n ')
359 | line_comment ('// the person calling the transfer_from contract')
360 | WHITE_SPACE ('\n ')
361 | contract ('contract')
362 | WHITE_SPACE (' ')
363 | ID_NAME ('transfer_from')
364 | ( ('(')
365 | ID_NAME ('message_sender')
366 | comma (',')
367 | WHITE_SPACE (' ')
368 | ID_NAME ('from')
369 | comma (',')
370 | WHITE_SPACE (' ')
371 | ID_NAME ('to')
372 | comma (',')
373 | WHITE_SPACE (' ')
374 | ID_NAME ('amount')
375 | comma (',')
376 | WHITE_SPACE (' ')
377 | ID_NAME ('rtn')
378 | ) (')')
379 | WHITE_SPACE (' ')
380 | = ('=')
381 | WHITE_SPACE (' ')
382 | { ('{')
383 | WHITE_SPACE ('\n ')
384 | for ('for')
385 | WHITE_SPACE (' ')
386 | ( ('(')
387 | ID_NAME ('balances')
388 | WHITE_SPACE (' ')
389 | < ('<')
390 | - ('-')
391 | WHITE_SPACE (' ')
392 | ID_NAME ('balances_channel')
393 | WHITE_SPACE ('\n ')
394 | ; (';')
395 | WHITE_SPACE (' ')
396 | ID_NAME ('allowed')
397 | WHITE_SPACE (' ')
398 | < ('<')
399 | - ('-')
400 | WHITE_SPACE (' ')
401 | ID_NAME ('allowed_channel')
402 | ) (')')
403 | WHITE_SPACE (' ')
404 | { ('{')
405 | WHITE_SPACE ('\n ')
406 | new ('new')
407 | WHITE_SPACE (' ')
408 | ID_NAME ('x')
409 | comma (',')
410 | WHITE_SPACE (' ')
411 | ID_NAME ('y')
412 | comma (',')
413 | WHITE_SPACE (' ')
414 | ID_NAME ('z')
415 | WHITE_SPACE (' ')
416 | in ('in')
417 | WHITE_SPACE (' ')
418 | { ('{')
419 | WHITE_SPACE ('\n ')
420 | ID_NAME ('x')
421 | ! ('!')
422 | ( ('(')
423 | ID_NAME ('balances')
424 | . ('.')
425 | ID_NAME ('getOrElse')
426 | ( ('(')
427 | ID_NAME ('from')
428 | comma (',')
429 | WHITE_SPACE (' ')
430 | Integer ('0')
431 | ) (')')
432 | ) (')')
433 | WHITE_SPACE (' ')
434 | | ('|')
435 | WHITE_SPACE ('\n ')
436 | ID_NAME ('y')
437 | ! ('!')
438 | ( ('(')
439 | ID_NAME ('allowed')
440 | . ('.')
441 | ID_NAME ('getOrElse')
442 | ( ('(')
443 | ID_NAME ('from')
444 | comma (',')
445 | WHITE_SPACE (' ')
446 | ID_NAME ('message_sender')
447 | comma (',')
448 | WHITE_SPACE (' ')
449 | Integer ('0')
450 | ) (')')
451 | ) (')')
452 | WHITE_SPACE (' ')
453 | | ('|')
454 | WHITE_SPACE ('\n ')
455 | ID_NAME ('z')
456 | ! ('!')
457 | ( ('(')
458 | ID_NAME ('balances')
459 | . ('.')
460 | ID_NAME ('getOrElse')
461 | ( ('(')
462 | ID_NAME ('to')
463 | comma (',')
464 | WHITE_SPACE (' ')
465 | Integer ('0')
466 | ) (')')
467 | ) (')')
468 | WHITE_SPACE (' ')
469 | | ('|')
470 | WHITE_SPACE ('\n ')
471 | for ('for')
472 | WHITE_SPACE (' ')
473 | ( ('(')
474 | WHITE_SPACE (' ')
475 | ID_NAME ('balance_of_sender')
476 | WHITE_SPACE (' ')
477 | < ('<')
478 | - ('-')
479 | WHITE_SPACE (' ')
480 | ID_NAME ('x')
481 | WHITE_SPACE ('\n ')
482 | ; (';')
483 | WHITE_SPACE (' ')
484 | ID_NAME ('sender_allowed')
485 | WHITE_SPACE (' ')
486 | < ('<')
487 | - ('-')
488 | WHITE_SPACE (' ')
489 | ID_NAME ('y')
490 | WHITE_SPACE ('\n ')
491 | ; (';')
492 | WHITE_SPACE (' ')
493 | ID_NAME ('balance_of_receiver')
494 | WHITE_SPACE (' ')
495 | < ('<')
496 | - ('-')
497 | WHITE_SPACE (' ')
498 | ID_NAME ('z')
499 | WHITE_SPACE (' ')
500 | ) (')')
501 | WHITE_SPACE (' ')
502 | { ('{')
503 | WHITE_SPACE ('\n ')
504 | match ('match')
505 | WHITE_SPACE (' ')
506 | [ ('[')
507 | WHITE_SPACE ('\n ')
508 | ID_NAME ('balance_of_sender')
509 | WHITE_SPACE (' ')
510 | >= ('>=')
511 | WHITE_SPACE (' ')
512 | ID_NAME ('amount')
513 | comma (',')
514 | WHITE_SPACE ('\n ')
515 | ID_NAME ('sender_allowed')
516 | WHITE_SPACE (' ')
517 | >= ('>=')
518 | WHITE_SPACE (' ')
519 | ID_NAME ('amount')
520 | comma (',')
521 | WHITE_SPACE ('\n ')
522 | ID_NAME ('amount')
523 | WHITE_SPACE (' ')
524 | > ('>')
525 | WHITE_SPACE (' ')
526 | Integer ('0')
527 | comma (',')
528 | WHITE_SPACE ('\n ')
529 | ID_NAME ('balance_of_receiver')
530 | WHITE_SPACE (' ')
531 | + ('+')
532 | WHITE_SPACE (' ')
533 | ID_NAME ('amount')
534 | WHITE_SPACE (' ')
535 | > ('>')
536 | WHITE_SPACE (' ')
537 | ID_NAME ('balance_of_receiver')
538 | WHITE_SPACE ('\n ')
539 | ] (']')
540 | WHITE_SPACE (' ')
541 | { ('{')
542 | WHITE_SPACE ('\n ')
543 | [ ('[')
544 | true ('true')
545 | comma (',')
546 | WHITE_SPACE (' ')
547 | true ('true')
548 | comma (',')
549 | WHITE_SPACE (' ')
550 | true ('true')
551 | comma (',')
552 | WHITE_SPACE (' ')
553 | true ('true')
554 | ] (']')
555 | WHITE_SPACE (' ')
556 | => ('=>')
557 | WHITE_SPACE (' ')
558 | { ('{')
559 | WHITE_SPACE ('\n ')
560 | ID_NAME ('balances_channel')
561 | ! ('!')
562 | ( ('(')
563 | WHITE_SPACE ('\n ')
564 | ( ('(')
565 | ID_NAME ('balances')
566 | WHITE_SPACE ('\n ')
567 | . ('.')
568 | ID_NAME ('insert')
569 | ( ('(')
570 | ID_NAME ('from')
571 | comma (',')
572 | WHITE_SPACE (' ')
573 | ID_NAME ('balance_of_sender')
574 | WHITE_SPACE (' ')
575 | - ('-')
576 | WHITE_SPACE (' ')
577 | ID_NAME ('amount')
578 | ) (')')
579 | ) (')')
580 | WHITE_SPACE ('\n ')
581 | . ('.')
582 | ID_NAME ('insert')
583 | ( ('(')
584 | ID_NAME ('to')
585 | comma (',')
586 | WHITE_SPACE (' ')
587 | ID_NAME ('balance_of_receiver')
588 | WHITE_SPACE (' ')
589 | + ('+')
590 | WHITE_SPACE (' ')
591 | ID_NAME ('amount')
592 | ) (')')
593 | WHITE_SPACE ('\n ')
594 | ) (')')
595 | WHITE_SPACE (' ')
596 | | ('|')
597 | WHITE_SPACE ('\n ')
598 | ID_NAME ('allowed_channel')
599 | ! ('!')
600 | ( ('(')
601 | WHITE_SPACE ('\n ')
602 | ID_NAME ('allowed')
603 | . ('.')
604 | ID_NAME ('insert')
605 | ( ('(')
606 | ID_NAME ('from')
607 | comma (',')
608 | WHITE_SPACE (' ')
609 | ID_NAME ('message_sender')
610 | comma (',')
611 | WHITE_SPACE (' ')
612 | ID_NAME ('sender_allowed')
613 | WHITE_SPACE (' ')
614 | - ('-')
615 | WHITE_SPACE (' ')
616 | ID_NAME ('amount')
617 | ) (')')
618 | WHITE_SPACE ('\n ')
619 | ) (')')
620 | WHITE_SPACE (' ')
621 | | ('|')
622 | WHITE_SPACE ('\n ')
623 | ID_NAME ('rtn')
624 | ! ('!')
625 | ( ('(')
626 | true ('true')
627 | ) (')')
628 | WHITE_SPACE ('\n ')
629 | } ('}')
630 | WHITE_SPACE ('\n ')
631 | _ ('_')
632 | WHITE_SPACE (' ')
633 | => ('=>')
634 | WHITE_SPACE (' ')
635 | { ('{')
636 | WHITE_SPACE ('\n ')
637 | ID_NAME ('balances_channel')
638 | ! ('!')
639 | ( ('(')
640 | ID_NAME ('balances')
641 | ) (')')
642 | WHITE_SPACE (' ')
643 | | ('|')
644 | WHITE_SPACE ('\n ')
645 | ID_NAME ('allowed_channel')
646 | ! ('!')
647 | ( ('(')
648 | ID_NAME ('allowed')
649 | ) (')')
650 | WHITE_SPACE (' ')
651 | | ('|')
652 | WHITE_SPACE ('\n ')
653 | ID_NAME ('rtn')
654 | ! ('!')
655 | ( ('(')
656 | false ('false')
657 | ) (')')
658 | WHITE_SPACE ('\n ')
659 | } ('}')
660 | WHITE_SPACE ('\n ')
661 | } ('}')
662 | WHITE_SPACE ('\n ')
663 | } ('}')
664 | WHITE_SPACE ('\n ')
665 | } ('}')
666 | WHITE_SPACE ('\n ')
667 | } ('}')
668 | WHITE_SPACE ('\n ')
669 | } ('}')
670 | WHITE_SPACE (' ')
671 | | ('|')
672 | WHITE_SPACE ('\n ')
673 | line_comment ('// This is the way an address can pre-approve (delegate) the transfer of')
674 | WHITE_SPACE ('\n ')
675 | line_comment ('// a certain amount of tokens to some other address. This allows for')
676 | WHITE_SPACE ('\n ')
677 | line_comment ('// that other address, through the use of the transfer_from function,')
678 | WHITE_SPACE ('\n ')
679 | line_comment ('// to send up to that amount of tokens.')
680 | WHITE_SPACE ('\n ')
681 | contract ('contract')
682 | WHITE_SPACE (' ')
683 | ID_NAME ('approve')
684 | ( ('(')
685 | ID_NAME ('message_sender')
686 | comma (',')
687 | WHITE_SPACE (' ')
688 | ID_NAME ('spender')
689 | comma (',')
690 | WHITE_SPACE (' ')
691 | ID_NAME ('amount')
692 | comma (',')
693 | WHITE_SPACE (' ')
694 | ID_NAME ('rtn')
695 | ) (')')
696 | WHITE_SPACE (' ')
697 | = ('=')
698 | WHITE_SPACE (' ')
699 | { ('{')
700 | WHITE_SPACE ('\n ')
701 | for ('for')
702 | WHITE_SPACE (' ')
703 | ( ('(')
704 | ID_NAME ('allowed')
705 | WHITE_SPACE (' ')
706 | < ('<')
707 | - ('-')
708 | WHITE_SPACE (' ')
709 | ID_NAME ('allowed_channel')
710 | ) (')')
711 | WHITE_SPACE (' ')
712 | { ('{')
713 | WHITE_SPACE ('\n ')
714 | ID_NAME ('allowed_channel')
715 | ! ('!')
716 | ( ('(')
717 | ID_NAME ('allowed')
718 | . ('.')
719 | ID_NAME ('insert')
720 | ( ('(')
721 | ID_NAME ('message_sender')
722 | comma (',')
723 | ID_NAME ('spender')
724 | comma (',')
725 | ID_NAME ('amount')
726 | ) (')')
727 | ) (')')
728 | WHITE_SPACE (' ')
729 | | ('|')
730 | WHITE_SPACE ('\n ')
731 | ID_NAME ('rtn')
732 | ! ('!')
733 | ( ('(')
734 | true ('true')
735 | ) (')')
736 | WHITE_SPACE ('\n ')
737 | } ('}')
738 | WHITE_SPACE ('\n ')
739 | } ('}')
740 | WHITE_SPACE (' ')
741 | | ('|')
742 | WHITE_SPACE ('\n ')
743 | contract ('contract')
744 | WHITE_SPACE (' ')
745 | ID_NAME ('balance_of')
746 | ( ('(')
747 | ID_NAME ('owner')
748 | comma (',')
749 | WHITE_SPACE (' ')
750 | ID_NAME ('rtn')
751 | ) (')')
752 | WHITE_SPACE (' ')
753 | = ('=')
754 | WHITE_SPACE (' ')
755 | { ('{')
756 | WHITE_SPACE ('\n ')
757 | for ('for')
758 | WHITE_SPACE (' ')
759 | ( ('(')
760 | ID_NAME ('balances')
761 | WHITE_SPACE (' ')
762 | < ('<')
763 | - ('-')
764 | WHITE_SPACE (' ')
765 | ID_NAME ('balances_channel')
766 | ) (')')
767 | WHITE_SPACE (' ')
768 | { ('{')
769 | WHITE_SPACE ('\n ')
770 | ID_NAME ('rtn')
771 | ! ('!')
772 | ( ('(')
773 | ID_NAME ('balances')
774 | . ('.')
775 | ID_NAME ('getOrElse')
776 | ( ('(')
777 | ID_NAME ('owner')
778 | comma (',')
779 | WHITE_SPACE (' ')
780 | Integer ('0')
781 | ) (')')
782 | ) (')')
783 | WHITE_SPACE (' ')
784 | | ('|')
785 | WHITE_SPACE ('\n ')
786 | ID_NAME ('balances_channel')
787 | ! ('!')
788 | ( ('(')
789 | ID_NAME ('balances')
790 | ) (')')
791 | WHITE_SPACE ('\n ')
792 | } ('}')
793 | WHITE_SPACE ('\n ')
794 | } ('}')
795 | WHITE_SPACE (' ')
796 | | ('|')
797 | WHITE_SPACE ('\n ')
798 | contract ('contract')
799 | WHITE_SPACE (' ')
800 | ID_NAME ('allowance')
801 | ( ('(')
802 | ID_NAME ('owner')
803 | comma (',')
804 | WHITE_SPACE (' ')
805 | ID_NAME ('spender')
806 | comma (',')
807 | WHITE_SPACE (' ')
808 | ID_NAME ('rtn')
809 | ) (')')
810 | WHITE_SPACE (' ')
811 | = ('=')
812 | WHITE_SPACE (' ')
813 | { ('{')
814 | WHITE_SPACE ('\n ')
815 | for ('for')
816 | WHITE_SPACE (' ')
817 | ( ('(')
818 | ID_NAME ('allowed')
819 | WHITE_SPACE (' ')
820 | < ('<')
821 | - ('-')
822 | WHITE_SPACE (' ')
823 | ID_NAME ('allowed_channel')
824 | ) (')')
825 | WHITE_SPACE (' ')
826 | { ('{')
827 | WHITE_SPACE ('\n ')
828 | ID_NAME ('allowed_channel')
829 | ! ('!')
830 | ( ('(')
831 | ID_NAME ('allowed')
832 | ) (')')
833 | WHITE_SPACE (' ')
834 | | ('|')
835 | WHITE_SPACE ('\n ')
836 | ID_NAME ('rtn')
837 | ! ('!')
838 | ( ('(')
839 | ID_NAME ('allowed')
840 | . ('.')
841 | ID_NAME ('getOrElse')
842 | ( ('(')
843 | ID_NAME ('owner')
844 | comma (',')
845 | ID_NAME ('spender')
846 | comma (',')
847 | Integer ('0')
848 | ) (')')
849 | ) (')')
850 | WHITE_SPACE ('\n ')
851 | } ('}')
852 | WHITE_SPACE ('\n ')
853 | } ('}')
854 | WHITE_SPACE (' ')
855 | | ('|')
856 | WHITE_SPACE ('\n ')
857 | contract ('contract')
858 | WHITE_SPACE (' ')
859 | ID_NAME ('contract_owner')
860 | ( ('(')
861 | ID_NAME ('rtn')
862 | ) (')')
863 | WHITE_SPACE (' ')
864 | = ('=')
865 | WHITE_SPACE (' ')
866 | { ('{')
867 | WHITE_SPACE ('\n ')
868 | for ('for')
869 | WHITE_SPACE (' ')
870 | ( ('(')
871 | ID_NAME ('owner')
872 | WHITE_SPACE (' ')
873 | < ('<')
874 | - ('-')
875 | WHITE_SPACE (' ')
876 | ID_NAME ('owner_channel')
877 | ) (')')
878 | WHITE_SPACE (' ')
879 | { ('{')
880 | WHITE_SPACE ('\n ')
881 | ID_NAME ('owner_channel')
882 | ! ('!')
883 | ( ('(')
884 | ID_NAME ('owner')
885 | ) (')')
886 | WHITE_SPACE (' ')
887 | | ('|')
888 | WHITE_SPACE ('\n ')
889 | ID_NAME ('rtn')
890 | ! ('!')
891 | ( ('(')
892 | ID_NAME ('owner')
893 | ) (')')
894 | WHITE_SPACE ('\n ')
895 | } ('}')
896 | WHITE_SPACE ('\n ')
897 | } ('}')
898 | WHITE_SPACE (' ')
899 | | ('|')
900 | WHITE_SPACE ('\n ')
901 | ID_NAME ('return_channel')
902 | ! ('!')
903 | ( ('(')
904 | WHITE_SPACE ('\n ')
905 | ID_NAME ('Map')
906 | ( ('(')
907 | ) (')')
908 | . ('.')
909 | ID_NAME ('insertMany')
910 | ( ('(')
911 | StringLit ('"transfer"')
912 | comma (',')
913 | WHITE_SPACE (' ')
914 | ID_NAME ('transfer')
915 | comma (',')
916 | WHITE_SPACE (' ')
917 | StringLit ('"transfer_from"')
918 | comma (',')
919 | WHITE_SPACE (' ')
920 | ID_NAME ('transfer_from')
921 | comma (',')
922 | WHITE_SPACE ('\n ')
923 | StringLit ('"approve"')
924 | comma (',')
925 | WHITE_SPACE (' ')
926 | ID_NAME ('approve')
927 | comma (',')
928 | WHITE_SPACE (' ')
929 | StringLit ('"balance_of"')
930 | comma (',')
931 | WHITE_SPACE (' ')
932 | ID_NAME ('balance_of')
933 | comma (',')
934 | WHITE_SPACE (' ')
935 | StringLit ('"allowance"')
936 | comma (',')
937 | WHITE_SPACE (' ')
938 | ID_NAME ('allowance')
939 | comma (',')
940 | WHITE_SPACE ('\n ')
941 | StringLit ('"contract_owner"')
942 | comma (',')
943 | WHITE_SPACE (' ')
944 | ID_NAME ('contract_owner')
945 | ) (')')
946 | ) (')')
947 | WHITE_SPACE ('\n ')
948 | line_comment ('// TODO: Eventually just insert with compiler')
949 | WHITE_SPACE ('\n ')
950 | } ('}')
951 | WHITE_SPACE ('\n ')
952 | } ('}')
953 | WHITE_SPACE ('\n ')
954 | } ('}')
955 | WHITE_SPACE (' ')
956 | | ('|')
957 | WHITE_SPACE ('\n ')
958 | new ('new')
959 | WHITE_SPACE (' ')
960 | ID_NAME ('rtn')
961 | comma (',')
962 | WHITE_SPACE (' ')
963 | ID_NAME ('me')
964 | comma (',')
965 | WHITE_SPACE (' ')
966 | ID_NAME ('they')
967 | WHITE_SPACE (' ')
968 | in ('in')
969 | WHITE_SPACE (' ')
970 | { ('{')
971 | WHITE_SPACE ('\n ')
972 | ID_NAME ('token')
973 | ! ('!')
974 | ( ('(')
975 | ID_NAME ('me')
976 | comma (',')
977 | WHITE_SPACE (' ')
978 | Integer ('100')
979 | comma (',')
980 | WHITE_SPACE (' ')
981 | ID_NAME ('rtn')
982 | ) (')')
983 | WHITE_SPACE (' ')
984 | | ('|')
985 | WHITE_SPACE ('\n ')
986 | for ('for')
987 | WHITE_SPACE (' ')
988 | ( ('(')
989 | ID_NAME ('token_contract')
990 | WHITE_SPACE (' ')
991 | < ('<')
992 | - ('-')
993 | WHITE_SPACE (' ')
994 | ID_NAME ('rtn')
995 | ) (')')
996 | WHITE_SPACE (' ')
997 | { ('{')
998 | WHITE_SPACE ('\n ')
999 | new ('new')
1000 | WHITE_SPACE (' ')
1001 | ID_NAME ('unused_rtn')
1002 | comma (',')
1003 | WHITE_SPACE (' ')
1004 | ID_NAME ('balance_of_rtn')
1005 | WHITE_SPACE (' ')
1006 | in ('in')
1007 | WHITE_SPACE (' ')
1008 | { ('{')
1009 | WHITE_SPACE ('\n ')
1010 | @ ('@')
1011 | ID_NAME ('token_contract')
1012 | . ('.')
1013 | ID_NAME ('get')
1014 | ( ('(')
1015 | StringLit ('"transfer"')
1016 | ) (')')
1017 | ! ('!')
1018 | ( ('(')
1019 | ID_NAME ('me')
1020 | comma (',')
1021 | WHITE_SPACE (' ')
1022 | ID_NAME ('they')
1023 | comma (',')
1024 | WHITE_SPACE (' ')
1025 | Integer ('50')
1026 | comma (',')
1027 | WHITE_SPACE (' ')
1028 | ID_NAME ('unused_rtn')
1029 | ) (')')
1030 | WHITE_SPACE (' ')
1031 | | ('|')
1032 | WHITE_SPACE ('\n ')
1033 | @ ('@')
1034 | ID_NAME ('token_contract')
1035 | . ('.')
1036 | ID_NAME ('get')
1037 | ( ('(')
1038 | StringLit ('"balance_of"')
1039 | ) (')')
1040 | ! ('!')
1041 | ( ('(')
1042 | ID_NAME ('they')
1043 | comma (',')
1044 | WHITE_SPACE (' ')
1045 | ID_NAME ('balance_of_rtn')
1046 | ) (')')
1047 | WHITE_SPACE (' ')
1048 | | ('|')
1049 | WHITE_SPACE ('\n ')
1050 | for ('for')
1051 | WHITE_SPACE (' ')
1052 | ( ('(')
1053 | ID_NAME ('they_balance')
1054 | WHITE_SPACE (' ')
1055 | < ('<')
1056 | - ('-')
1057 | WHITE_SPACE (' ')
1058 | ID_NAME ('balance_of_rtn')
1059 | ) (')')
1060 | WHITE_SPACE (' ')
1061 | { ('{')
1062 | WHITE_SPACE ('\n ')
1063 | ID_NAME ('they_balance')
1064 | . ('.')
1065 | ID_NAME ('display')
1066 | ( ('(')
1067 | StringLit ('"\n"')
1068 | ) (')')
1069 | WHITE_SPACE ('\n ')
1070 | } ('}')
1071 | WHITE_SPACE ('\n ')
1072 | } ('}')
1073 | WHITE_SPACE ('\n ')
1074 | } ('}')
1075 | WHITE_SPACE ('\n ')
1076 | } ('}')
1077 | WHITE_SPACE (' ')
1078 | | ('|')
1079 | WHITE_SPACE ('\n ')
1080 | new ('new')
1081 | WHITE_SPACE (' ')
1082 | ID_NAME ('rtn2')
1083 | comma (',')
1084 | WHITE_SPACE (' ')
1085 | ID_NAME ('me2')
1086 | comma (',')
1087 | WHITE_SPACE (' ')
1088 | ID_NAME ('they2')
1089 | WHITE_SPACE (' ')
1090 | in ('in')
1091 | WHITE_SPACE (' ')
1092 | { ('{')
1093 | WHITE_SPACE ('\n ')
1094 | ID_NAME ('token')
1095 | ! ('!')
1096 | ( ('(')
1097 | ID_NAME ('me2')
1098 | comma (',')
1099 | WHITE_SPACE (' ')
1100 | Integer ('1000')
1101 | comma (',')
1102 | WHITE_SPACE (' ')
1103 | ID_NAME ('rtn2')
1104 | ) (')')
1105 | WHITE_SPACE (' ')
1106 | | ('|')
1107 | WHITE_SPACE ('\n ')
1108 | for ('for')
1109 | WHITE_SPACE (' ')
1110 | ( ('(')
1111 | ID_NAME ('token_contract2')
1112 | WHITE_SPACE (' ')
1113 | < ('<')
1114 | - ('-')
1115 | WHITE_SPACE (' ')
1116 | ID_NAME ('rtn2')
1117 | ) (')')
1118 | WHITE_SPACE (' ')
1119 | { ('{')
1120 | WHITE_SPACE ('\n ')
1121 | new ('new')
1122 | WHITE_SPACE (' ')
1123 | ID_NAME ('unused_rtn2')
1124 | comma (',')
1125 | WHITE_SPACE (' ')
1126 | ID_NAME ('balance_of_rtn2')
1127 | WHITE_SPACE (' ')
1128 | in ('in')
1129 | WHITE_SPACE (' ')
1130 | { ('{')
1131 | WHITE_SPACE ('\n ')
1132 | @ ('@')
1133 | ID_NAME ('token_contract2')
1134 | . ('.')
1135 | ID_NAME ('get')
1136 | ( ('(')
1137 | StringLit ('"transfer"')
1138 | ) (')')
1139 | ! ('!')
1140 | ( ('(')
1141 | ID_NAME ('me2')
1142 | comma (',')
1143 | WHITE_SPACE (' ')
1144 | ID_NAME ('they2')
1145 | comma (',')
1146 | WHITE_SPACE (' ')
1147 | Integer ('500')
1148 | comma (',')
1149 | WHITE_SPACE (' ')
1150 | ID_NAME ('unused_rtn2')
1151 | ) (')')
1152 | WHITE_SPACE (' ')
1153 | | ('|')
1154 | WHITE_SPACE ('\n ')
1155 | @ ('@')
1156 | ID_NAME ('token_contract2')
1157 | . ('.')
1158 | ID_NAME ('get')
1159 | ( ('(')
1160 | StringLit ('"balance_of"')
1161 | ) (')')
1162 | ! ('!')
1163 | ( ('(')
1164 | ID_NAME ('they2')
1165 | comma (',')
1166 | WHITE_SPACE (' ')
1167 | ID_NAME ('balance_of_rtn2')
1168 | ) (')')
1169 | WHITE_SPACE (' ')
1170 | | ('|')
1171 | WHITE_SPACE ('\n ')
1172 | for ('for')
1173 | WHITE_SPACE (' ')
1174 | ( ('(')
1175 | ID_NAME ('they_balance2')
1176 | WHITE_SPACE (' ')
1177 | < ('<')
1178 | - ('-')
1179 | WHITE_SPACE (' ')
1180 | ID_NAME ('balance_of_rtn2')
1181 | ) (')')
1182 | WHITE_SPACE (' ')
1183 | { ('{')
1184 | WHITE_SPACE ('\n ')
1185 | ID_NAME ('they_balance2')
1186 | . ('.')
1187 | ID_NAME ('display')
1188 | ( ('(')
1189 | StringLit ('"\n"')
1190 | ) (')')
1191 | WHITE_SPACE ('\n ')
1192 | } ('}')
1193 | WHITE_SPACE ('\n ')
1194 | } ('}')
1195 | WHITE_SPACE ('\n ')
1196 | } ('}')
1197 | WHITE_SPACE ('\n ')
1198 | } ('}')
1199 | WHITE_SPACE ('\n ')
1200 | line_comment ('// Once we have a registry, we can do registry_channel!(token) to save the contract there')
1201 | WHITE_SPACE ('\n')
1202 | } ('}')
1203 |
--------------------------------------------------------------------------------