├── .gitattributes
├── .github
└── workflows
│ ├── main.yml
│ └── publish.yml
├── .gitignore
├── Artwork
├── RainLisp-ASCII-Art.txt
├── RainLisp-ASCII.txt
├── RainLisp-Colored-128x128.png
├── RainLisp-Colored.png
├── RainLisp-Colored.svg
├── RainLisp-Negative-Page.svg
├── RainLisp-Negative.png
├── RainLisp-Negative.svg
├── RainLisp-Page.svg
├── RainLisp-Short.svg
├── RainLisp.ico
├── RainLisp.png
└── RainLisp.svg
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── RainLisp.sln
├── RainLisp
├── AbstractSyntaxTree
│ ├── Application.cs
│ ├── Assignment.cs
│ ├── Begin.cs
│ ├── Body.cs
│ ├── BooleanLiteral.cs
│ ├── Definition.cs
│ ├── Delay.cs
│ ├── Expression.cs
│ ├── Identifier.cs
│ ├── If.cs
│ ├── Lambda.cs
│ ├── Node.cs
│ ├── NumberLiteral.cs
│ ├── Program.cs
│ ├── Quotable.cs
│ ├── Quote.cs
│ └── StringLiteral.cs
├── DerivedExpressions
│ ├── And.cs
│ ├── Condition.cs
│ ├── ConditionClause.cs
│ ├── ConditionElseClause.cs
│ ├── ConsStream.cs
│ ├── Let.cs
│ ├── LetClause.cs
│ ├── Or.cs
│ └── Transformations.cs
├── Docs
│ ├── common-libraries.md
│ ├── common-libraries
│ │ ├── append.md
│ │ ├── caaaar.md
│ │ ├── caaadr.md
│ │ ├── caaar.md
│ │ ├── caadar.md
│ │ ├── caaddr.md
│ │ ├── caadr.md
│ │ ├── caar.md
│ │ ├── cadaar.md
│ │ ├── cadadr.md
│ │ ├── cadar.md
│ │ ├── caddar.md
│ │ ├── cadddr.md
│ │ ├── caddr.md
│ │ ├── cadr.md
│ │ ├── cdaaar.md
│ │ ├── cdaadr.md
│ │ ├── cdaar.md
│ │ ├── cdadar.md
│ │ ├── cdaddr.md
│ │ ├── cdadr.md
│ │ ├── cdar.md
│ │ ├── cddaar.md
│ │ ├── cddadr.md
│ │ ├── cddar.md
│ │ ├── cdddar.md
│ │ ├── cddddr.md
│ │ ├── cdddr.md
│ │ ├── cddr.md
│ │ ├── cdr-stream.md
│ │ ├── filter-stream.md
│ │ ├── filter.md
│ │ ├── flatmap.md
│ │ ├── fold-left.md
│ │ ├── fold-right.md
│ │ ├── force.md
│ │ ├── length.md
│ │ ├── make-range-stream.md
│ │ ├── map-stream.md
│ │ ├── map.md
│ │ ├── reduce.md
│ │ └── reverse.md
│ ├── contents.md
│ ├── dotnet-integration.md
│ ├── primitives.md
│ ├── primitives
│ │ ├── add-days.md
│ │ ├── add-hours.md
│ │ ├── add-milliseconds.md
│ │ ├── add-minutes.md
│ │ ├── add-months.md
│ │ ├── add-seconds.md
│ │ ├── add-years.md
│ │ ├── car.md
│ │ ├── cdr.md
│ │ ├── ceiling.md
│ │ ├── cons.md
│ │ ├── datetime-to-string.md
│ │ ├── day.md
│ │ ├── days-diff.md
│ │ ├── debug.md
│ │ ├── display.md
│ │ ├── divide.md
│ │ ├── equal.md
│ │ ├── error.md
│ │ ├── eval.md
│ │ ├── floor.md
│ │ ├── greater-or-equal.md
│ │ ├── greater.md
│ │ ├── hour.md
│ │ ├── hours-diff.md
│ │ ├── index-of-string.md
│ │ ├── is-null.md
│ │ ├── is-pair.md
│ │ ├── is-utc.md
│ │ ├── less-or-equal.md
│ │ ├── less.md
│ │ ├── list.md
│ │ ├── make-date.md
│ │ ├── make-datetime.md
│ │ ├── millisecond.md
│ │ ├── milliseconds-diff.md
│ │ ├── minus.md
│ │ ├── minute.md
│ │ ├── minutes-diff.md
│ │ ├── modulo.md
│ │ ├── month.md
│ │ ├── multiply.md
│ │ ├── newline.md
│ │ ├── nil.md
│ │ ├── not.md
│ │ ├── now.md
│ │ ├── number-to-string.md
│ │ ├── parse-datetime.md
│ │ ├── parse-number-culture.md
│ │ ├── parse-number.md
│ │ ├── plus.md
│ │ ├── replace-string.md
│ │ ├── round.md
│ │ ├── second.md
│ │ ├── seconds-diff.md
│ │ ├── set-car!.md
│ │ ├── set-cdr!.md
│ │ ├── string-length.md
│ │ ├── substring.md
│ │ ├── to-local.md
│ │ ├── to-lower.md
│ │ ├── to-upper.md
│ │ ├── to-utc.md
│ │ ├── trace.md
│ │ ├── utc-now.md
│ │ ├── xor.md
│ │ └── year.md
│ ├── quick-start.md
│ ├── quick-start
│ │ ├── advanced-data-structures.md
│ │ ├── begin.md
│ │ ├── booleans.md
│ │ ├── comment.md
│ │ ├── conditionals.md
│ │ ├── cps.md
│ │ ├── data-directed-programming.md
│ │ ├── datetimes.md
│ │ ├── encapsulation.md
│ │ ├── img
│ │ │ ├── 1d-table.drawio
│ │ │ ├── 1d-table.png
│ │ │ ├── 2d-table.drawio
│ │ │ ├── 2d-table.png
│ │ │ ├── complex-pair.drawio
│ │ │ ├── complex-pair.png
│ │ │ ├── list.drawio
│ │ │ ├── list.png
│ │ │ ├── simple-pair.drawio
│ │ │ └── simple-pair.png
│ │ ├── let.md
│ │ ├── list-operations.md
│ │ ├── lists.md
│ │ ├── loops.md
│ │ ├── message-passing.md
│ │ ├── metaprogramming.md
│ │ ├── numbers.md
│ │ ├── pairs.md
│ │ ├── procedures.md
│ │ ├── quotes.md
│ │ ├── strings.md
│ │ ├── user-data-structures.md
│ │ └── variables.md
│ ├── special-forms-derived-expressions.md
│ └── special-forms-derived-expressions
│ │ ├── and.md
│ │ ├── begin.md
│ │ ├── cond.md
│ │ ├── cons-stream.md
│ │ ├── define.md
│ │ ├── delay.md
│ │ ├── function-application.md
│ │ ├── if.md
│ │ ├── lambda.md
│ │ ├── let.md
│ │ ├── or.md
│ │ ├── quote.md
│ │ └── set!.md
├── DotNetIntegration
│ └── Extensions.cs
├── ErrorMessages.cs
├── Evaluation
│ ├── EvaluationEnvironment.cs
│ ├── EvaluationResultPrintVisitor.cs
│ ├── EvaluatorVisitor.cs
│ ├── Exceptions.cs
│ ├── IEnvironmentFactory.cs
│ ├── IEvaluationEnvironment.cs
│ ├── IEvaluationResultVisitor.cs
│ ├── IEvaluatorVisitor.cs
│ ├── IProcedureApplicationVisitor.cs
│ ├── PrimitiveOperation.cs
│ ├── ProcedureApplicationVisitor.cs
│ └── Results
│ │ ├── BoolDatum.cs
│ │ ├── DateTimeDatum.cs
│ │ ├── EvaluationResult.cs
│ │ ├── IPrimitiveDatum.cs
│ │ ├── MemoizedUserProcedure.cs
│ │ ├── Nil.cs
│ │ ├── NumberDatum.cs
│ │ ├── Pair.cs
│ │ ├── PrimitiveDatum.cs
│ │ ├── PrimitiveProcedure.cs
│ │ ├── QuoteSymbol.cs
│ │ ├── StringDatum.cs
│ │ ├── Unspecified.cs
│ │ └── UserProcedure.cs
├── Grammar
│ ├── Delimiters.cs
│ ├── Keywords.cs
│ ├── Lexical Grammar.md
│ ├── NumberSpecialChars.cs
│ ├── Primitives.cs
│ ├── StringEscapableChars.cs
│ └── Syntax Grammar.md
├── IDebugInfo.cs
├── IInterpreter.cs
├── Interpreter.cs
├── InterpreterDelegates.cs
├── LispLibraries.cs
├── Parsing
│ ├── Extensions.cs
│ ├── IParser.cs
│ ├── Parser.cs
│ ├── ParsingException.cs
│ └── TokenConsumer.cs
├── RainLisp.csproj
└── Tokenization
│ ├── Exceptions.cs
│ ├── Extensions.cs
│ ├── ITokenizer.cs
│ ├── NumberTokenizer.cs
│ ├── StringTokenizer.cs
│ ├── Token.cs
│ ├── TokenType.cs
│ └── Tokenizer.cs
├── RainLispTests
├── AbstractSyntaxTrees
│ ├── 00.json
│ ├── 01.json
│ ├── 02.json
│ ├── 03.json
│ ├── 04.json
│ ├── 05.json
│ ├── 06.json
│ ├── 07.json
│ ├── 08.json
│ ├── 09.json
│ ├── 10.json
│ ├── 11.json
│ ├── 12.json
│ ├── 13.json
│ ├── 14.json
│ ├── 15.json
│ ├── 16.json
│ ├── 17.json
│ ├── 18.json
│ ├── 19.json
│ ├── 20.json
│ ├── 21.json
│ ├── 22.json
│ ├── 23.json
│ ├── 24.json
│ ├── 25.json
│ ├── 26.json
│ ├── 27.json
│ ├── 28.json
│ ├── 29.json
│ ├── 30.json
│ ├── 31.json
│ ├── 32.json
│ ├── 33.json
│ ├── 34.json
│ ├── 35.json
│ ├── 36.json
│ ├── 37.json
│ ├── 38.json
│ ├── 39.json
│ ├── 40.json
│ ├── 41.json
│ ├── 42.json
│ ├── 43.json
│ ├── 44.json
│ ├── 45.json
│ ├── 46.json
│ ├── 47.json
│ ├── 48.json
│ ├── 49.json
│ ├── 50.json
│ ├── 51.json
│ ├── 52.json
│ ├── 53.json
│ ├── 54.json
│ ├── 55.json
│ ├── 56.json
│ ├── 57.json
│ ├── 58.json
│ ├── 59.json
│ ├── 60.json
│ └── 61.json
├── DotNetIntegrationExtensionsTests.cs
├── EnvironmentTests.cs
├── Environments
│ ├── 00.json
│ ├── 01.json
│ ├── 02.json
│ ├── 03.json
│ ├── 04.json
│ ├── 05.json
│ ├── 06.json
│ ├── 07.json
│ ├── 08.json
│ ├── 09.json
│ └── 10.json
├── EvaluatorErrorTests.cs
├── EvaluatorTests.cs
├── ParserTests.cs
├── PrintEvaluationResultTests.cs
├── RainLispTests.csproj
├── TestDebugInfo.cs
├── TestableEnvironment.cs
├── TestableEnvironmentContractResolver.cs
├── TestableEnvironmentFactory.cs
├── TokenizerTests.cs
├── Usings.cs
└── Utils.cs
└── nuget.md
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Unit Test With Coverage
2 | on:
3 | push:
4 | branches:
5 | - master
6 | #workflow_dispatch:
7 | jobs:
8 | build:
9 | runs-on: windows-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 | - name: Setup .NET
13 | uses: actions/setup-dotnet@v1
14 | with:
15 | dotnet-version: 6.0.405
16 | - name: Restore dependencies
17 | run: dotnet restore
18 | - name: Build
19 | run: dotnet build --no-restore
20 | - name: Test
21 | run: dotnet test --collect:"XPlat Code Coverage;Format=opencover"
22 | #dotnet test -p:CollectCoverage=true -p:CoverletOutput=TestResults/ -p:CoverletOutputFormat=opencover --no-build --verbosity normal RainLispTests/
23 | - name: Copy File
24 | run: cp RainLispTests\TestResults\*\coverage.opencover.xml RainLispTests\TestResults
25 | - name: Create Test Coverage Badge
26 | uses: simon-k/dotnet-code-coverage-badge@v1.0.0
27 | id: create_coverage_badge
28 | with:
29 | label: Unit Test Coverage
30 | color: brightgreen
31 | path: RainLispTests/TestResults/coverage.opencover.xml
32 | gist-filename: code-coverage.json
33 | gist-id: 3ad6a6f6575320603cc8edf6171b42e8
34 | gist-auth-token: ${{ secrets.GIST_AUTH_TOKEN }}
35 | - name: Print code coverage
36 | run: echo "Code coverage percentage ${{steps.create_coverage_badge.outputs.percentage}}%"
37 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish to Nuget
2 | on:
3 | # Manual workflow.
4 | workflow_dispatch:
5 | jobs:
6 | build:
7 | runs-on: windows-latest
8 | steps:
9 | - uses: actions/checkout@v3
10 |
11 | - name: Setup .NET
12 | uses: actions/setup-dotnet@v3
13 | with:
14 | dotnet-version: 6
15 |
16 | - name: Restore dependencies
17 | run: dotnet restore
18 |
19 | - name: Build Release
20 | run: dotnet build --configuration Release --no-restore
21 |
22 | - name: Test
23 | run: dotnet test
24 |
25 | - name: Publish to Nuget.org
26 | run: dotnet nuget push RainLisp\bin\Release\*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json
27 |
--------------------------------------------------------------------------------
/Artwork/RainLisp-ASCII-Art.txt:
--------------------------------------------------------------------------------
1 |
2 | ╓████▄
3 | ╔██▀▀███.
4 | █" ╙██
5 | ,,,w╥«»»»«╥ww,, ,╓▒»»H***╜▀***H»»w╓,
6 | ╓@╙` "╙ `╠H~»HHH≡~~╖,
7 | ╓H*""`╙╙* ╙╗
8 | ╙≡╖, ,╓╝
9 | '""*^*H~~~~~~~─**╜""**^^*j▄▄▄▄▄▄*^**""` `
10 | ╓▄▄▄▄▄; ,████ ██
11 | ▐█┘ ▐█W ▀▀ ┌████ ▐█▌ '▀▀
12 | █▌ ██┘ ╓╥╖,▄ ,▄▄ ,▄▄ ▄▄ ┌████ ██ ,╓▄▄ ╓▄╖╓∞ ,▄▄ ,▄▄
13 | ▐█▀&█▀╙ ▄▀ █▌ █▌ █▌ƒ"]█M ┌████ ▐█▌ ▄ ]█╛ ▐█ ▐" ██╜ ▐█
14 | ]█▌ ██ █▌ ██ ▐█ ▐█▀ █▌ ┌████` ███, ,█▌ █▌ ▀█▄ ▐█' ██
15 | ██ ╙█▌ ▐█, ╓╣█░╥ ]█░a ,█▀ ▐█,∞ ╓████` ███████ ▐█,≡ ▌ '█M █▌ ,█▀
16 | "▀▀▀╙ ╙▀╙` ▀▀╙ "▀" "▀╙ ╙▀ ╙▀' ▀▀▀▀` ╘▀▀▀└ ╙▀" └▀╙*╙' ██▀*╙└
17 | ╓█⌐
18 |
19 |
--------------------------------------------------------------------------------
/Artwork/RainLisp-ASCII.txt:
--------------------------------------------------------------------------------
1 | _____ _ __ _
2 | | __ \ (_) \ \ (_)
3 | | |__) |__ _ _ _ __ \ \ _ ___ _ __
4 | | _ // _` | | '_ \ > \ | / __| '_ \
5 | | | \ \ (_| | | | | |/ ^ \| \__ \ |_) |
6 | |_| \_\__,_|_|_| |_/_/ \_\_|___/ .__/
7 | | |
8 | |_|
9 |
10 |
--------------------------------------------------------------------------------
/Artwork/RainLisp-Colored-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/Artwork/RainLisp-Colored-128x128.png
--------------------------------------------------------------------------------
/Artwork/RainLisp-Colored.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/Artwork/RainLisp-Colored.png
--------------------------------------------------------------------------------
/Artwork/RainLisp-Negative.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/Artwork/RainLisp-Negative.png
--------------------------------------------------------------------------------
/Artwork/RainLisp.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/Artwork/RainLisp.ico
--------------------------------------------------------------------------------
/Artwork/RainLisp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/Artwork/RainLisp.png
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to "RainLisp" will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](http://keepachangelog.com/).
6 |
7 | Semantic versioning is followed.
8 |
9 | ## [Unreleased]
10 |
11 | ### Added
12 |
13 | ### Fixed
14 |
15 | ### Changed
16 |
17 | ### Removed
18 |
19 | ## [1.4.0] - 2025-02-16
20 |
21 | ### Added
22 | - `delay` special form for supporting delayed expressions.
23 | - `force` library procedure to force the evaluation of a delayed expression.
24 | - `cons-stream` derived expression for creating infinite streams.
25 | - `cdr-stream` library procedure to enable walking through a stream.
26 | - `make-range-stream` library procedure to make a numerical range stream.
27 | - `map-stream` library procedure that projects elements of a stream.
28 | - `filter-stream` library procedure that filters elements of a stream.
29 |
30 | ### Fixed
31 |
32 | ### Changed
33 |
34 | ### Removed
35 |
36 | ## [1.3.0] - 2024-06-30
37 |
38 | ### Added
39 | - `parse-number-culture` primitive procedure. #146
40 |
41 | ## [1.2.0] - 2024-02-18
42 |
43 | ### Added
44 | - Add extension methods in the `RainLisp.DotNetIntegration` namespace for easier consumption by .NET systems.
45 |
46 | ## [1.1.0] - 2024-01-28
47 |
48 | ### Added
49 | - Ceiling and floor primitive procedures.
50 |
51 | ## [1.0.0] - 2023-07-20
52 |
53 | Initial release.
54 |
55 | ## [1.0.0-beta.1] - 2023-07-11
56 |
57 | Initial beta release.
58 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [2023] [RainLisp]
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RainLisp [](https://twitter.com/intent/tweet?text=RainLisp,%20a%20.NET%20LISP%20implementation.&url=https://github.com/chr1st0scli/RainLisp&hashtags=lisp,Dotnet,developers)
2 |
3 | 
4 | [](https://www.nuget.org/packages/RainLisp/)
5 | [](LICENSE.txt)
6 |
7 | 
8 |
9 | RainLisp is a programming language, belonging to the LISP family of languages, with many similarities to Scheme. It is implemented entirely in C# and therefore brought to the .NET ecosystem.
10 |
11 | It is not intended to replace your everyday programming language at work. Though, you can integrate it with your existing systems to allow for their configuration in terms of code.
12 |
13 | For example, one can build a system where parts of its computations or workflow logic is implemented in RainLisp. Its simplicity and capabilities make it ideal for using it like a DSL (Domain Specific Language) that integrates with your .NET system.
14 |
15 | Additionally, you can easily extend it to implement your own LISP dialect or replace some of its components, like the tokenizer and parser, and reuse the evaluator to easily build an entirely different but compatible programming language.
16 |
17 | You can also use it independently, using its code editor to learn LISP, play around with it and have fun!
18 |
19 | ## Documentation
20 | - [Tutorial](RainLisp/Docs/quick-start.md)
21 | - [Specification](RainLisp/Docs/contents.md)
22 | - [.NET Integration](RainLisp/Docs/dotnet-integration.md)
23 |
24 | ## Tools
25 | - [RainLisp Console](https://github.com/chr1st0scli/RainLispConsole)
26 | - [RainLisp VSCode](https://marketplace.visualstudio.com/items?itemName=chr1st0scli.rainlisp-vscode)
27 |
--------------------------------------------------------------------------------
/RainLisp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.1.32421.90
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RainLisp", "RainLisp\RainLisp.csproj", "{D03792CD-1531-4C4F-9BFF-F5A3DA995C68}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RainLispTests", "RainLispTests\RainLispTests.csproj", "{C14530F8-F41B-4388-AEDC-179135AF2197}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {D03792CD-1531-4C4F-9BFF-F5A3DA995C68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {D03792CD-1531-4C4F-9BFF-F5A3DA995C68}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {D03792CD-1531-4C4F-9BFF-F5A3DA995C68}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {D03792CD-1531-4C4F-9BFF-F5A3DA995C68}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {C14530F8-F41B-4388-AEDC-179135AF2197}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {C14530F8-F41B-4388-AEDC-179135AF2197}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {C14530F8-F41B-4388-AEDC-179135AF2197}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {C14530F8-F41B-4388-AEDC-179135AF2197}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {CA9C6E36-FA20-4DCC-89A3-04ECD627FF58}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Begin.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// Begin expression, i.e. a code block, in the abstract syntax tree.
8 | ///
9 | public class Begin : Expression
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// A list of expressions in the code block.
15 | public Begin(IList expressions)
16 | => Expressions = expressions;
17 |
18 | ///
19 | /// Gets or sets the expressions in the code block.
20 | ///
21 | public IList Expressions { get; init; }
22 |
23 | ///
24 | /// Evaluates the begin code block and returns the result.
25 | ///
26 | /// The visitor that implements the evaluation.
27 | /// The environment the evaluation occurs in.
28 | /// The result of the evaluation.
29 | /// An error occurs during the evaluation of this instance.
30 | public override EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment)
31 | => visitor.EvaluateBegin(this, environment);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Body.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// Body of a function in the abstract syntax tree.
8 | ///
9 | public class Body : Node
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// An optional list of definitions.
15 | /// The list of expressions included in the function's body.
16 | public Body(IList? definitions, IList expressions)
17 | {
18 | Definitions = definitions;
19 | Expressions = expressions;
20 | }
21 |
22 | ///
23 | /// Gets or sets the optional list of definitions.
24 | ///
25 | public IList? Definitions { get; init; }
26 |
27 | ///
28 | /// Gets or sets the list of expressions included in the function's body.
29 | ///
30 | public IList Expressions { get; init; }
31 |
32 | ///
33 | /// Evaluates the function's body and returns the result.
34 | ///
35 | /// The visitor that implements the evaluation.
36 | /// The environment the evaluation occurs in.
37 | /// The result of the evaluation.
38 | /// An error occurs during the evaluation of this instance.
39 | public override EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment)
40 | => visitor.EvaluateBody(this, environment);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/BooleanLiteral.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// Boolean literal expression in the abstract syntax tree.
8 | ///
9 | public class BooleanLiteral : Expression
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The contained boolean value.
15 | public BooleanLiteral(bool value)
16 | => Value = value;
17 |
18 | ///
19 | /// Gets or sets the contained boolean value of the current literal.
20 | ///
21 | public bool Value { get; init; }
22 |
23 | ///
24 | /// Evaluates the boolean literal and returns the result.
25 | ///
26 | /// The visitor that implements the evaluation.
27 | /// The environment the evaluation occurs in.
28 | /// The result of the evaluation.
29 | public override EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment)
30 | => visitor.EvaluateBooleanLiteral(this);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Delay.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// Delayed expression in the abstract syntax tree.
8 | ///
9 | public class Delay : Expression
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The expression whose evaluation is meant to be delayed.
15 | public Delay(Expression delayed)
16 | => Delayed = delayed;
17 |
18 | ///
19 | /// Gets ot sets the expression whose evaluation is meant to be delayed.
20 | ///
21 | public Expression Delayed { get; init; }
22 |
23 | ///
24 | /// Evaluates the delay expression and returns the result.
25 | ///
26 | /// The visitor that implements the evaluation.
27 | /// The environment the evaluation occurs in.
28 | /// The result of the evaluation.
29 | public override EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment)
30 | => visitor.EvaluateDelay(this, environment);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Expression.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.AbstractSyntaxTree
2 | {
3 | ///
4 | /// Expression in the abstract syntax tree.
5 | ///
6 | public abstract class Expression : Node, IDebugInfo
7 | {
8 | ///
9 | /// Gets or sets the expression's line in the source code.
10 | ///
11 | public uint Line { get; set; }
12 |
13 | ///
14 | /// Gets or sets the expression's starting character position on the in the source code.
15 | ///
16 | public uint Position { get; set; }
17 |
18 | ///
19 | /// Gets or sets if relevant debugging info has been set.
20 | ///
21 | public bool HasDebugInfo { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Identifier.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// Identifier in the abstract syntax tree.
8 | ///
9 | public class Identifier : Expression
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The name of the identifier.
15 | public Identifier(string name)
16 | => Name = name;
17 |
18 | ///
19 | /// Gets or sets the name of the identifier.
20 | ///
21 | public string Name { get; init; }
22 |
23 | ///
24 | /// Evaluates the identifier and returns the result.
25 | ///
26 | /// The visitor that implements the evaluation.
27 | /// The environment the evaluation occurs in.
28 | /// The result of the evaluation.
29 | /// This identifier's is not defined.
30 | public override EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment)
31 | => visitor.EvaluateIdentifier(this, environment);
32 |
33 | ///
34 | /// Returns a string that represents the current identifier.
35 | ///
36 | /// A string that represents the current identifier.
37 | public override string? ToString() => Name;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Lambda.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// Lambda, i.e. an anonymous function, in the abstract syntax tree.
8 | ///
9 | public class Lambda : Expression
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// An optional list of parameters for the function.
15 | /// The body of the function.
16 | public Lambda(IList? parameters, Body body)
17 | {
18 | Parameters = parameters;
19 | Body = body;
20 | }
21 |
22 | ///
23 | /// Gets or sets the function's optional parameters.
24 | ///
25 | public IList? Parameters { get; init; }
26 |
27 | ///
28 | /// Gets or sets the function's body.
29 | ///
30 | public Body Body { get; init; }
31 |
32 | ///
33 | /// Evaluates the lambda expression and returns the result.
34 | ///
35 | /// The visitor that implements the evaluation.
36 | /// The environment the evaluation occurs in.
37 | /// The result of the evaluation.
38 | public override EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment)
39 | => visitor.EvaluateLambda(this, environment);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Node.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// Node of the abstract syntax tree.
8 | ///
9 | public abstract class Node
10 | {
11 | ///
12 | /// Gets the name of the node's runtime type.
13 | ///
14 | public string TypeName => GetType().Name;
15 |
16 | ///
17 | /// Evaluates the current abstract syntax tree node and returns the result.
18 | ///
19 | /// The visitor that implements the evaluation.
20 | /// The environment the evaluation occurs in.
21 | /// The result of the evaluation.
22 | public abstract EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment);
23 |
24 | ///
25 | /// Returns a string that represents the current node.
26 | ///
27 | /// A string that represents the current node.
28 | public override string? ToString() => TypeName;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/NumberLiteral.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// Number literal expression in the abstract syntax tree.
8 | ///
9 | public class NumberLiteral : Expression
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The contained numeric value.
15 | public NumberLiteral(double value)
16 | => Value = value;
17 |
18 | ///
19 | /// Gets or sets the contained numeric value of the current literal.
20 | ///
21 | public double Value { get; init; }
22 |
23 | ///
24 | /// Evaluates the number literal and returns the result.
25 | ///
26 | /// The visitor that implements the evaluation.
27 | /// The environment the evaluation occurs in.
28 | /// The result of the evaluation.
29 | public override EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment)
30 | => visitor.EvaluateNumberLiteral(this);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Program.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.AbstractSyntaxTree
2 | {
3 | ///
4 | /// Represents the root of the abstract syntax tree.
5 | ///
6 | public class Program
7 | {
8 | ///
9 | /// Gets or sets the alternating definitions and expressions that constitute the program.
10 | ///
11 | public IList? DefinitionsAndExpressions { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Quotable.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.AbstractSyntaxTree
2 | {
3 | ///
4 | /// The quotable part of a quote expression in the abstract syntax tree.
5 | ///
6 | public class Quotable
7 | {
8 | ///
9 | /// Initializes a new instance of the class that either contains text or a list of other quotables.
10 | ///
11 | /// The optional text of the quotable.
12 | /// An optional list of other quotables.
13 | public Quotable(string? text, IList? quotables = null)
14 | {
15 | Text = text;
16 | Quotables = quotables;
17 | }
18 |
19 | ///
20 | /// Gets or sets the optional text of the quotable.
21 | ///
22 | public string? Text { get; init; }
23 |
24 | ///
25 | /// Gets or sets the optional list of other quotables.
26 | ///
27 | public IList? Quotables { get; init; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/Quote.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// Quote expression in the abstract syntax tree.
8 | ///
9 | public class Quote : Expression
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The quotable contained in the quote epression.
15 | public Quote(Quotable quotable)
16 | => Quotable = quotable;
17 |
18 | ///
19 | /// Gets or sets the quotable contained in the quote expression.
20 | ///
21 | public Quotable Quotable { get; init; }
22 |
23 | ///
24 | /// Evaluates the quote expression and returns the result.
25 | ///
26 | /// The visitor that implements the evaluation.
27 | /// The environment the evaluation occurs in.
28 | /// The result of the evaluation.
29 | public override EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment)
30 | => visitor.EvaluateQuote(this, environment);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/RainLisp/AbstractSyntaxTree/StringLiteral.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 | using RainLisp.Evaluation.Results;
3 |
4 | namespace RainLisp.AbstractSyntaxTree
5 | {
6 | ///
7 | /// String literal expression in the abstract syntax tree.
8 | ///
9 | public class StringLiteral : Expression
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The contained string value.
15 | public StringLiteral(string value)
16 | => Value = value;
17 |
18 | ///
19 | /// Gets or sets the contained string value of the current literal.
20 | ///
21 | public string Value { get; init; }
22 |
23 | ///
24 | /// Evaluates the string literal and returns the result.
25 | ///
26 | /// The visitor that implements the evaluation.
27 | /// The environment the evaluation occurs in.
28 | /// The result of the evaluation.
29 | public override EvaluationResult AcceptVisitor(IEvaluatorVisitor visitor, IEvaluationEnvironment environment)
30 | => visitor.EvaluateStringLiteral(this);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/RainLisp/DerivedExpressions/And.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.AbstractSyntaxTree;
2 |
3 | namespace RainLisp.DerivedExpressions
4 | {
5 | ///
6 | /// List of expressions combined in a boolean logical "and" fashion as described in the syntax grammar.
7 | ///
8 | public class And
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// A list of expressions to be combined in a boolean logical "and" fashion.
14 | public And(IList expressions)
15 | => Expressions = expressions;
16 |
17 | ///
18 | /// Gets or sets the list of expressions to be combined in a boolean logical "and" fashion.
19 | ///
20 | public IList Expressions { get; init; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/RainLisp/DerivedExpressions/Condition.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.DerivedExpressions
2 | {
3 | ///
4 | /// Condition expression as described in the syntax grammar.
5 | ///
6 | public class Condition
7 | {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// A list of conditional clauses contained in the condition.
12 | /// An optional alternative clause.
13 | public Condition(IList clauses, ConditionElseClause? elseClause)
14 | {
15 | Clauses = clauses;
16 | ElseClause = elseClause;
17 | }
18 |
19 | ///
20 | /// Gets or sets the list of conditional clauses contained in the condition.
21 | ///
22 | public IList Clauses { get; init; }
23 |
24 | ///
25 | /// Gets or sets the optional alternative clause.
26 | ///
27 | public ConditionElseClause? ElseClause { get; init; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/RainLisp/DerivedExpressions/ConditionClause.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.AbstractSyntaxTree;
2 |
3 | namespace RainLisp.DerivedExpressions
4 | {
5 | ///
6 | /// Condition clause, that is part of a condition, as described in the syntax grammar.
7 | ///
8 | public class ConditionClause
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The expression whose value determines if are to be evaluated.
14 | /// A list of expressions that are to be evaluated if is true.
15 | public ConditionClause(Expression predicate, IList expressions)
16 | {
17 | Predicate = predicate;
18 | Expressions = expressions;
19 | }
20 |
21 | ///
22 | /// Gets or sets the expression whose value determines if are to be evaluated.
23 | ///
24 | public Expression Predicate { get; init; }
25 |
26 | ///
27 | /// Gets or sets the list of expressions that are to be evaluated if is true.
28 | ///
29 | public IList Expressions { get; init; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/RainLisp/DerivedExpressions/ConditionElseClause.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.AbstractSyntaxTree;
2 |
3 | namespace RainLisp.DerivedExpressions
4 | {
5 | ///
6 | /// Condition else clause, that is part of a condition, as described in the syntax grammar.
7 | ///
8 | public class ConditionElseClause
9 | {
10 | ///
11 | /// Initializes a new instannce of the class.
12 | ///
13 | /// A list of expressions that are to be evaluated if all other condition clauses were not chosen.
14 | public ConditionElseClause(IList expressions)
15 | => Expressions = expressions;
16 |
17 | ///
18 | /// Gets or sets the list of expressions that are to be evaluated if all other condition clauses were not chosen.
19 | ///
20 | public IList Expressions { get; init; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/RainLisp/DerivedExpressions/ConsStream.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.AbstractSyntaxTree;
2 |
3 | namespace RainLisp.DerivedExpressions
4 | {
5 | ///
6 | /// Cons stream expression as described in the syntax grammar.
7 | ///
8 | public class ConsStream
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The first constituent expression.
14 | /// The second constituent expression.
15 | public ConsStream(Expression first, Expression second)
16 | {
17 | First = first;
18 | Second = second;
19 | }
20 |
21 | ///
22 | /// Gets or sets the first constituent expression.
23 | ///
24 | public Expression First { get; init; }
25 |
26 | ///
27 | /// Gets or sets the second constituent expression.
28 | ///
29 | public Expression Second { get; init; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/RainLisp/DerivedExpressions/Let.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.AbstractSyntaxTree;
2 |
3 | namespace RainLisp.DerivedExpressions
4 | {
5 | ///
6 | /// Let expression as described in the syntax grammar.
7 | ///
8 | public class Let
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// A list of clauses that setup definitions with local scope for the .
14 | /// The body to be evaluated.
15 | public Let(IList clauses, Body body)
16 | {
17 | Clauses = clauses;
18 | Body = body;
19 | }
20 |
21 | ///
22 | /// Gets or sets the list of clauses that setup definitions with local scope for the .
23 | ///
24 | public IList Clauses { get; init; }
25 |
26 | ///
27 | /// Gets or sets the body to be evaluated.
28 | ///
29 | public Body Body { get; init; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/RainLisp/DerivedExpressions/LetClause.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.AbstractSyntaxTree;
2 |
3 | namespace RainLisp.DerivedExpressions
4 | {
5 | ///
6 | /// Let clause, that is part of a let expression, as described in the syntax grammar.
7 | ///
8 | public class LetClause
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// An identifier name that is to be bound to 's value with local scope for the let expression's body.
14 | /// The expression whose value is to be bound to .
15 | public LetClause(string identifierName, Expression expression)
16 | {
17 | IdentifierName = identifierName;
18 | Expression = expression;
19 | }
20 |
21 | ///
22 | /// Gets or sets the identifier name that is to be bound to 's value with local scope for the let expression's body.
23 | ///
24 | public string IdentifierName { get; init; }
25 |
26 | ///
27 | /// Gets or sets the expression whose value is to be bound to .
28 | ///
29 | public Expression Expression { get; init; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/RainLisp/DerivedExpressions/Or.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.AbstractSyntaxTree;
2 |
3 | namespace RainLisp.DerivedExpressions
4 | {
5 | ///
6 | /// List of expressions combined in a boolean logical "or" fashion as described in the syntax grammar.
7 | ///
8 | public class Or
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// A list of expressions to be combined in a boolean logical "or" fashion.
14 | public Or(IList expressions)
15 | => Expressions = expressions;
16 |
17 | ///
18 | /// Gets or sets the list of expressions to be combined in a boolean logical "or" fashion.
19 | ///
20 | public IList Expressions { get; init; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries.md:
--------------------------------------------------------------------------------
1 | # Common Libraries
2 |
3 | Common libraries are procedures that are defined in the language itself.
4 |
5 | ## List Operations
6 | - [append](common-libraries/append.md)
7 | - [filter](common-libraries/filter.md)
8 | - [flatmap](common-libraries/flatmap.md)
9 | - [fold-left](common-libraries/fold-left.md)
10 | - [fold-right](common-libraries/fold-right.md)
11 | - [length](common-libraries/length.md)
12 | - [map](common-libraries/map.md)
13 | - [reduce](common-libraries/reduce.md)
14 | - [reverse](common-libraries/reverse.md)
15 |
16 | ## Stream Operations
17 | - [cdr-stream](common-libraries/cdr-stream.md)
18 | - [filter-stream](common-libraries/filter-stream.md)
19 | - [force](common-libraries/force.md)
20 | - [make-range-stream](common-libraries/make-range-stream.md)
21 | - [map-stream](common-libraries/map-stream.md)
22 |
23 | ## car & cdr Flavors
24 | - [cddr](common-libraries/cddr.md)
25 | - [cadr](common-libraries/cadr.md)
26 | - [caar](common-libraries/caar.md)
27 | - [cdar](common-libraries/cdar.md)
28 | - [cdddr](common-libraries/cdddr.md)
29 | - [caddr](common-libraries/caddr.md)
30 | - [caadr](common-libraries/caadr.md)
31 | - [caaar](common-libraries/caaar.md)
32 | - [cdaar](common-libraries/cdaar.md)
33 | - [cddar](common-libraries/cddar.md)
34 | - [cdadr](common-libraries/cdadr.md)
35 | - [cadar](common-libraries/cadar.md)
36 | - [cddddr](common-libraries/cddddr.md)
37 | - [cadddr](common-libraries/cadddr.md)
38 | - [caaddr](common-libraries/caaddr.md)
39 | - [caaadr](common-libraries/caaadr.md)
40 | - [caaaar](common-libraries/caaaar.md)
41 | - [cdaaar](common-libraries/cdaaar.md)
42 | - [cddaar](common-libraries/cddaar.md)
43 | - [cdddar](common-libraries/cdddar.md)
44 | - [cdadar](common-libraries/cdadar.md)
45 | - [cadadr](common-libraries/cadadr.md)
46 | - [cdaddr](common-libraries/cdaddr.md)
47 | - [cddadr](common-libraries/cddadr.md)
48 | - [cadaar](common-libraries/cadaar.md)
49 | - [caadar](common-libraries/caadar.md)
50 | - [cdaadr](common-libraries/cdaadr.md)
51 | - [caddar](common-libraries/caddar.md)
52 |
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/append.md:
--------------------------------------------------------------------------------
1 | # append
2 | ```scheme
3 | (define (append list1 list2)
4 | (fold-right cons list2 list1))
5 | ```
6 | Returns a new list by appending *list2* to *list1*.
7 |
8 | ## Example
9 | ```scheme
10 | (append (list 1 2 3) (list 4 5 6))
11 | ```
12 | -> *(1 2 3 4 5 6)*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/caaaar.md:
--------------------------------------------------------------------------------
1 | # caaaar
2 | ```scheme
3 | (define (caaaar sequence)
4 | (car (caaar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (caaaar sequence)
12 | ```
13 | -> *1*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/caaadr.md:
--------------------------------------------------------------------------------
1 | # caaadr
2 | ```scheme
3 | (define (caaadr sequence)
4 | (car (caadr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (caaadr sequence)
12 | ```
13 | -> *9*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/caaar.md:
--------------------------------------------------------------------------------
1 | # caaar
2 | ```scheme
3 | (define (caaar sequence)
4 | (car (caar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))))
11 | (caaar sequence)
12 | ```
13 | -> *1*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/caadar.md:
--------------------------------------------------------------------------------
1 | # caadar
2 | ```scheme
3 | (define (caadar sequence)
4 | (car (cadar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (caadar sequence)
12 | ```
13 | -> *5*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/caaddr.md:
--------------------------------------------------------------------------------
1 | # caaddr
2 | ```scheme
3 | (define (caaddr sequence)
4 | (car (caddr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (caaddr sequence)
12 | ```
13 | -> *13*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/caadr.md:
--------------------------------------------------------------------------------
1 | # caadr
2 | ```scheme
3 | (define (caadr sequence)
4 | (car (cadr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))))
11 | (caadr sequence)
12 | ```
13 | -> *5*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/caar.md:
--------------------------------------------------------------------------------
1 | # caar
2 | ```scheme
3 | (define (caar sequence)
4 | (car (car sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons 1 2) (cons 3 4)))
11 | (caar sequence)
12 | ```
13 | -> *1*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cadaar.md:
--------------------------------------------------------------------------------
1 | # cadaar
2 | ```scheme
3 | (define (cadaar sequence)
4 | (car (cdaar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cadaar sequence)
12 | ```
13 | -> *3*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cadadr.md:
--------------------------------------------------------------------------------
1 | # cadadr
2 | ```scheme
3 | (define (cadadr sequence)
4 | (car (cdadr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cadadr sequence)
12 | ```
13 | -> *11*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cadar.md:
--------------------------------------------------------------------------------
1 | # cadar
2 | ```scheme
3 | (define (cadar sequence)
4 | (car (cdar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))))
11 | (cadar sequence)
12 | ```
13 | -> *3*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/caddar.md:
--------------------------------------------------------------------------------
1 | # caddar
2 | ```scheme
3 | (define (caddar sequence)
4 | (car (cddar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (caddar sequence)
12 | ```
13 | -> *7*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cadddr.md:
--------------------------------------------------------------------------------
1 | # cadddr
2 | ```scheme
3 | (define (cadddr sequence)
4 | (car (cdddr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cadddr sequence)
12 | ```
13 | -> *15*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/caddr.md:
--------------------------------------------------------------------------------
1 | # caddr
2 | ```scheme
3 | (define (caddr sequence)
4 | (car (cddr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))))
11 | (caddr sequence)
12 | ```
13 | -> *7*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cadr.md:
--------------------------------------------------------------------------------
1 | # cadr
2 | ```scheme
3 | (define (cadr sequence)
4 | (car (cdr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons 1 2) (cons 3 4)))
11 | (cadr sequence)
12 | ```
13 | -> *3*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdaaar.md:
--------------------------------------------------------------------------------
1 | # cdaaar
2 | ```scheme
3 | (define (cdaaar sequence)
4 | (cdr (caaar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cdaaar sequence)
12 | ```
13 | -> *2*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdaadr.md:
--------------------------------------------------------------------------------
1 | # cdaadr
2 | ```scheme
3 | (define (cdaadr sequence)
4 | (cdr (caadr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cdaadr sequence)
12 | ```
13 | -> *10*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdaar.md:
--------------------------------------------------------------------------------
1 | # cdaar
2 | ```scheme
3 | (define (cdaar sequence)
4 | (cdr (caar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))))
11 | (cdaar sequence)
12 | ```
13 | -> *2*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdadar.md:
--------------------------------------------------------------------------------
1 | # cdadar
2 | ```scheme
3 | (define (cdadar sequence)
4 | (cdr (cadar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cdadar sequence)
12 | ```
13 | -> *6*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdaddr.md:
--------------------------------------------------------------------------------
1 | # cdaddr
2 | ```scheme
3 | (define (cdaddr sequence)
4 | (cdr (caddr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cdaddr sequence)
12 | ```
13 | -> *14*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdadr.md:
--------------------------------------------------------------------------------
1 | # cdadr
2 | ```scheme
3 | (define (cdadr sequence)
4 | (cdr (cadr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))))
11 | (cdadr sequence)
12 | ```
13 | -> *6*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdar.md:
--------------------------------------------------------------------------------
1 | # cdar
2 | ```scheme
3 | (define (cdar sequence)
4 | (cdr (car sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons 1 2) (cons 3 4)))
11 | (cdar sequence)
12 | ```
13 | -> *2*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cddaar.md:
--------------------------------------------------------------------------------
1 | # cddaar
2 | ```scheme
3 | (define (cddaar sequence)
4 | (cdr (cdaar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cddaar sequence)
12 | ```
13 | -> *4*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cddadr.md:
--------------------------------------------------------------------------------
1 | # cddadr
2 | ```scheme
3 | (define (cddadr sequence)
4 | (cdr (cdadr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cddadr sequence)
12 | ```
13 | -> *12*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cddar.md:
--------------------------------------------------------------------------------
1 | # cddar
2 | ```scheme
3 | (define (cddar sequence)
4 | (cdr (cdar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))))
11 | (cddar sequence)
12 | ```
13 | -> *4*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdddar.md:
--------------------------------------------------------------------------------
1 | # cdddar
2 | ```scheme
3 | (define (cdddar sequence)
4 | (cdr (cddar sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cdddar sequence)
12 | ```
13 | -> *8*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cddddr.md:
--------------------------------------------------------------------------------
1 | # cddddr
2 | ```scheme
3 | (define (cddddr sequence)
4 | (cdr (cdddr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))) (cons (cons (cons 9 10) (cons 11 12)) (cons (cons 13 14) (cons 15 16)))))
11 | (cddddr sequence)
12 | ```
13 | -> *16*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdddr.md:
--------------------------------------------------------------------------------
1 | # cdddr
2 | ```scheme
3 | (define (cdddr sequence)
4 | (cdr (cddr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons (cons 1 2) (cons 3 4)) (cons (cons 5 6) (cons 7 8))))
11 | (cdddr sequence)
12 | ```
13 | -> *8*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cddr.md:
--------------------------------------------------------------------------------
1 | # cddr
2 | ```scheme
3 | (define (cddr sequence)
4 | (cdr (cdr sequence)))
5 | ```
6 | Helper for accessing a particular element based on [car](../primitives/car.md) and [cdr](../primitives/cdr.md) primitives.
7 |
8 | ## Example
9 | ```scheme
10 | (define sequence (cons (cons 1 2) (cons 3 4)))
11 | (cddr sequence)
12 | ```
13 | -> *4*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/cdr-stream.md:
--------------------------------------------------------------------------------
1 | # cdr-stream
2 | ```scheme
3 | (define (cdr-stream stream)
4 | (force (cdr stream)))
5 | ```
6 | Returns the rest of a stream, i.e. its next element by forcing its promise to be fulfilled and a promise for the rest of it.
7 |
8 | ## Example
9 | ```scheme
10 | (cdr-stream (make-range-stream 1 8000000))
11 | ```
12 | -> *(2 . [UserProcedure] Parameters: 0)*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/filter-stream.md:
--------------------------------------------------------------------------------
1 | # filter-stream
2 | ```scheme
3 | (define (filter-stream predicate stream)
4 | (cond ((null? stream) nil)
5 | ((predicate (car stream))
6 | (cons-stream (car stream) (filter-stream predicate (cdr-stream stream))))
7 | (else (filter-stream predicate (cdr-stream stream)))))
8 | ```
9 | Returns a new stream containing the first element of a stream that satisfies a condition and a promise for the rest of them.
10 |
11 | > *predicate* is a procedure accepting a single argument (each element of *stream* at a time) and its result is evaluated as a boolean.
12 |
13 | > *stream* is the stream to filter.
14 |
15 | ## Examples
16 | ```scheme
17 | ; Filter the even numbers of a stream.
18 | ; It returns the first even number and a promise to filter the rest of them.
19 | (filter-stream
20 | (lambda (n) (= 0 (% n 2)))
21 | (make-range-stream 1 8))
22 | ```
23 | -> *(2 . [UserProcedure] Parameters: 0)*
24 |
25 | ```scheme
26 | ; Create a stream of evens.
27 | (define evens
28 | (filter-stream
29 | (lambda (n) (= 0 (% n 2)))
30 | (make-range-stream 1 8)))
31 |
32 | ; Find the second even.
33 | (car (cdr-stream evens))
34 | ```
35 | -> *4*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/filter.md:
--------------------------------------------------------------------------------
1 | # filter
2 | ```scheme
3 | (define (filter predicate sequence)
4 | (cond ((null? sequence) nil)
5 | ((predicate (car sequence))
6 | (cons (car sequence) (filter predicate (cdr sequence))))
7 | (else (filter predicate (cdr sequence)))))
8 | ```
9 | Returns a new list containing only the elements of a list that satisfy a condition.
10 |
11 | > *predicate* is a procedure accepting a single argument (each element of *sequence* at a time) and its result is evaluated as a boolean.
12 |
13 | > *sequence* is the list to filter.
14 |
15 | ## Example
16 | ```scheme
17 | ; Filter the even numbers of a list.
18 | (filter
19 | (lambda (n) (= 0 (% n 2)))
20 | (list 1 2 3 4 5 6 7 8))
21 | ```
22 | -> *(2 4 6 8)*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/flatmap.md:
--------------------------------------------------------------------------------
1 | # flatmap
2 | ```scheme
3 | (define (flatmap proc sequence)
4 | (fold-right append nil (map proc sequence)))
5 | ```
6 | Projects each element of a list to a list of many and flattens the results in a single list.
7 |
8 | > *proc* is a procedure accepting a single argument (each element of *sequence* at a time) and returning a list.
9 |
10 | > *sequence* is the list whose each element is mapped to many.
11 |
12 | ## Example
13 | ```scheme
14 | ; Get a list where each number is followed by a boolean specifying if it is even.
15 | (flatmap
16 | (lambda (n) (list n (= 0 (% n 2))))
17 | (list 1 2 3 4 5 6))
18 | ```
19 | -> *(1 false 2 true 3 false 4 true 5 false 6 true)*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/fold-left.md:
--------------------------------------------------------------------------------
1 | # fold-left
2 | ```scheme
3 | (define (fold-left op initial sequence)
4 | (define (iter result rest)
5 | (if (null? rest)
6 | result
7 | (iter (op result (car rest)) (cdr rest))))
8 | (iter initial sequence))
9 | ```
10 | Returns a result by accumulating a computation on a list from left to right.
11 |
12 | > *op* is a procedure accepting two arguments and returning the result of accumulation on each step.
13 |
14 | > *initial* is the seed of the accumulation.
15 |
16 | > *sequence* is the list to accumulate.
17 |
18 | The first *op* call's arguments is the initial seed followed by the first element of the list.
19 |
20 | ## Example
21 | ```scheme
22 | ; ((10 - 1) - 2) - 3
23 | (fold-left - 10 (list 1 2 3))
24 | ```
25 | -> *4*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/fold-right.md:
--------------------------------------------------------------------------------
1 | # fold-right
2 | ```scheme
3 | (define (fold-right op initial sequence)
4 | (if (null? sequence)
5 | initial
6 | (op (car sequence) (fold-right op initial (cdr sequence)))))
7 | ```
8 |
9 | Returns a result by accumulating a computation on a list from right to left.
10 |
11 | > *op* is a procedure accepting two arguments and returning the result of accumulation on each step.
12 |
13 | > *initial* is the seed of the accumulation.
14 |
15 | > *sequence* is the list to accumulate.
16 |
17 | The first *op* call's arguments is the last element of the list followed by the initial seed.
18 |
19 | ## Example
20 | ```scheme
21 | ; 1 - (2 - (3 - 10))
22 | (fold-right - 10 (list 1 2 3))
23 | ```
24 | -> *-8*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/force.md:
--------------------------------------------------------------------------------
1 | # force
2 | ```scheme
3 | (define (force proc)
4 | (proc))
5 | ```
6 | Executes a procedure and returns its result. Typically the procedure is a promise, i.e. a delayed expression
7 | that results from [delay](../special-forms-derived-expressions/delay.md).
8 |
9 | > *proc* is the procedure to execute, typically a promise to evaluate an expression.
10 |
11 | ## Example
12 | ```scheme
13 | (force (delay 4))
14 | ```
15 | -> *4*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/length.md:
--------------------------------------------------------------------------------
1 | # length
2 | ```scheme
3 | (define (length sequence)
4 | (fold-left (lambda (count n) (+ count 1)) 0 sequence))
5 | ```
6 | Returns the length of a list.
7 |
8 | ## Example
9 | ```scheme
10 | (length (list 1 2 3 4))
11 | ```
12 | -> *4*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/make-range-stream.md:
--------------------------------------------------------------------------------
1 | # make-range-stream
2 | ```scheme
3 | (define (make-range-stream start end)
4 | (if (> start end)
5 | nil
6 | (cons-stream start (make-range-stream (+ start 1) end))))
7 | ```
8 | Returns a new stream of numeric values ranging from *start* until *end*. The first numeric value is evaluated and the evaluation of the rest is deferred,
9 | i.e. delayed until explicitly requested. If *start* is greater than *end*, [nil](../primitives/nil.md) is returned.
10 |
11 | > *start* is the first value of the stream which is immediately evaluated.
12 |
13 | > *end* is the last value of the stream.
14 |
15 | ## Example
16 | ```scheme
17 | ; Returns a stream made of the first element and a promise to fulfill the rest of it.
18 | (make-range-stream 7 5000000)
19 | ```
20 | -> *(7 . [UserProcedure] Parameters: 0)*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/map-stream.md:
--------------------------------------------------------------------------------
1 | # map-stream
2 | ```scheme
3 | (define (map-stream proc stream)
4 | (if (null? stream)
5 | nil
6 | (cons-stream (proc (car stream)) (map-stream proc (cdr-stream stream)))))
7 | ```
8 | Returns a new stream with the projection of the first element and a promise for the projection of the rest of them.
9 |
10 | > *proc* is a procedure accepting a single argument (each element of *stream* at a time) and returning a projection.
11 |
12 | > *stream* is the delayed list whose each element is mapped to another one on demand.
13 |
14 | ## Examples
15 | ```scheme
16 | ; Multiply each number in a stream by 10.
17 | ; It returns the projected first element and a promise to project the rest of them.
18 | (map-stream
19 | (lambda (n) (* n 10))
20 | (make-range-stream 1 5))
21 | ```
22 | -> *(10 . [UserProcedure] Parameters: 0)*
23 |
24 | ```scheme
25 | ; Create a stream of multiples of 10.
26 | (define projected-stream
27 | (map-stream
28 | (lambda (n) (* n 10))
29 | (make-range-stream 1 5)))
30 |
31 | ; Project the second element.
32 | (car (cdr-stream projected-stream))
33 | ```
34 | -> *20*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/map.md:
--------------------------------------------------------------------------------
1 | # map
2 | ```scheme
3 | (define (map proc sequence)
4 | (if (null? sequence)
5 | nil
6 | (cons (proc (car sequence)) (map proc (cdr sequence)))))
7 | ```
8 | Returns a new list with the projections of a given list's elements.
9 |
10 | > *proc* is a procedure accepting a single argument (each element of *sequence* at a time) and returning a projection.
11 |
12 | > *sequence* is the list whose each element is mapped to another one.
13 |
14 | ## Example
15 | ```scheme
16 | ; Multiply each number by 10.
17 | (map
18 | (lambda (n) (* n 10))
19 | (list 1 2 3 4 5))
20 | ```
21 | -> *(10 20 30 40 50)*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/reduce.md:
--------------------------------------------------------------------------------
1 | # reduce
2 | ```scheme
3 | (define (reduce op sequence)
4 | (cond ((null? sequence) nil)
5 | ((null? (cdr sequence)) (car sequence))
6 | (else (fold-left op (car sequence) (cdr sequence)))))
7 | ```
8 | Returns a result by accumulating a computation on a list from left to right.
9 |
10 | > *op* is a procedure accepting two arguments and returning the result of accumulation on each step.
11 |
12 | > *sequence* is the list to accumulate.
13 |
14 | ## Example
15 | ```scheme
16 | (reduce + (list 1 2 3 4))
17 | ```
18 | -> *10*
--------------------------------------------------------------------------------
/RainLisp/Docs/common-libraries/reverse.md:
--------------------------------------------------------------------------------
1 | # reverse
2 | ```scheme
3 | (define (reverse sequence)
4 | (fold-left (lambda (x y) (cons y x)) nil sequence))
5 | ```
6 | Returns a new list by reversing the elements of a given one.
7 |
8 | ## Example
9 | ```scheme
10 | (reverse (list 1 2 3 4))
11 | ```
12 | -> *(4 3 2 1)*
--------------------------------------------------------------------------------
/RainLisp/Docs/contents.md:
--------------------------------------------------------------------------------
1 | # Specification
2 |
3 | ## Main Features
4 |
5 | 1. RainLisp is a LISP dialect with many similarities to Scheme, which means it emphasizes on simplicity.
6 | 1. It is a functional programming language, but not purely functional as it supports mutation.
7 | 1. As a LISP dialect, it uses prefix notation.
8 | 1. It adopts an applicative order of evaluation, which means that a function's arguments are evaluated before
9 | the function is applied to them.
10 | 1. It is dynamic.
11 | 1. It is interpreted on the .NET runtime.
12 |
13 | ## Grammars
14 |
15 | - [Lexical Grammar](<../Grammar/Lexical Grammar.md>)
16 | - [Syntax Grammar](<../Grammar/Syntax Grammar.md>)
17 |
18 | ## Manual
19 |
20 | - [Special Forms & Derived Expressions](special-forms-derived-expressions.md)
21 | - [Primitives](primitives.md)
22 | - [Common Libraries](common-libraries.md)
23 |
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/add-days.md:
--------------------------------------------------------------------------------
1 | # add-days
2 | ```scheme
3 | (add-days datetime num)
4 | ```
5 | Returns a new datetime that adds the specified number of days to the specified datetime.
6 |
7 | > *datetime* to add days to.
8 |
9 | > *num* is the whole and fractional number of days to add, which can be positive or negative.
10 |
11 | ## Example
12 | ```scheme
13 | (add-days (make-date 2023 5 1) 30)
14 | ```
15 | -> *2023-05-31 00:00:00.000*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/add-hours.md:
--------------------------------------------------------------------------------
1 | # add-hours
2 | ```scheme
3 | (add-hours datetime num)
4 | ```
5 | Returns a new datetime that adds the specified number of hours to the specified datetime.
6 |
7 | > *datetime* to add hours to.
8 |
9 | > *num* is the whole and fractional number of hours to add, which can be positive or negative.
10 |
11 | ## Example
12 | ```scheme
13 | (add-hours (make-date 2023 12 31) 5.5)
14 | ```
15 | -> *2023-12-31 05:30:00.000*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/add-milliseconds.md:
--------------------------------------------------------------------------------
1 | # add-milliseconds
2 | ```scheme
3 | (add-milliseconds datetime num)
4 | ```
5 | Returns a new datetime that adds the specified number of milliseconds to the specified datetime.
6 |
7 | > *datetime* to add milliseconds to.
8 |
9 | > *num* is the whole and fractional number of milliseconds to add, which can be positive or negative. Note that it is rounded to the nearest integer.
10 |
11 | ## Example
12 | ```scheme
13 | (add-milliseconds (make-date 2023 12 31) 400.5)
14 | ```
15 | -> *2023-12-31 00:00:00.401*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/add-minutes.md:
--------------------------------------------------------------------------------
1 | # add-minutes
2 | ```scheme
3 | (add-minutes datetime num)
4 | ```
5 | Returns a new datetime that adds the specified number of minutes to the specified datetime.
6 |
7 | > *datetime* to add minutes to.
8 |
9 | > *num* the whole and fractional number of minutes to add, which can be positive or negative.
10 |
11 | ## Example
12 | ```scheme
13 | (add-minutes (make-date 2023 12 31) 25.5)
14 | ```
15 | -> *2023-12-31 00:25:30.000*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/add-months.md:
--------------------------------------------------------------------------------
1 | # add-months
2 | ```scheme
3 | (add-months datetime num)
4 | ```
5 | Returns a new datetime that adds the specified number of months to the specified datetime.
6 |
7 | > *datetime* to add months to.
8 |
9 | > *num* is the number of months to add which can be positive or negative.
10 |
11 | Note that only the integral part of months is considered.
12 |
13 | ## Example
14 | ```scheme
15 | (add-months (make-date 2023 5 31) 7)
16 | ```
17 | -> *2023-12-31 00:00:00.000*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/add-seconds.md:
--------------------------------------------------------------------------------
1 | # add-seconds
2 | ```scheme
3 | (add-seconds datetime num)
4 | ```
5 | Returns a new datetime that adds the specified number of seconds to the specified datetime.
6 |
7 | > *datetime* to add seconds to.
8 |
9 | > *num* is the whole and fractional number of seconds to add, which can be positive or negative.
10 |
11 | ## Example
12 | ```scheme
13 | (add-seconds (make-date 2023 12 31) 25.5)
14 | ```
15 | -> *2023-12-31 00:00:25.500*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/add-years.md:
--------------------------------------------------------------------------------
1 | # add-years
2 | ```scheme
3 | (add-years datetime num)
4 | ```
5 | Returns a new datetime that adds the specified number of years to the specified datetime.
6 |
7 | > *datetime* to add years to.
8 |
9 | > *num* is the number of years to add which can be positive or negative.
10 |
11 | Note that only the integral part of years is considered.
12 |
13 | ## Example
14 | ```scheme
15 | (add-years (make-date 2023 12 31) 7)
16 | ```
17 | -> *2030-12-31 00:00:00.000*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/car.md:
--------------------------------------------------------------------------------
1 | # car
2 | ```scheme
3 | (car pair)
4 | ```
5 | Returns the first element of a pair.
6 |
7 | ## Examples
8 | ```scheme
9 | (car (cons "RainLisp" 2023))
10 | ```
11 | -> *"RainLisp"*
12 |
13 | ```scheme
14 | (car (cons (cons 'Name "RainLisp") (cons 'Copyright 2023)))
15 | ```
16 | -> *(Name . "RainLisp")*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/cdr.md:
--------------------------------------------------------------------------------
1 | # cdr
2 | ```scheme
3 | (cdr pair)
4 | ```
5 | Returns the second element of a pair.
6 |
7 | ## Examples
8 | ```scheme
9 | (cdr (cons "RainLisp" 2023))
10 | ```
11 | -> *2023*
12 |
13 | ```scheme
14 | (cdr (cons (cons 'Name "RainLisp") (cons 'Copyright 2023)))
15 | ```
16 | -> *(Copyright . 2023)*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/ceiling.md:
--------------------------------------------------------------------------------
1 | # ceiling
2 | ```scheme
3 | (ceiling num)
4 | ```
5 | Rounds a numeric value to the smallest integral that is greater than or equal to it.
6 |
7 | > *num* is a numeric value to round.
8 |
9 | ## Examples
10 | ```scheme
11 | (ceiling 231.23456)
12 | ```
13 | -> *232*
14 |
15 | ```scheme
16 | (ceiling 231.56789)
17 | ```
18 | -> *232*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/cons.md:
--------------------------------------------------------------------------------
1 | # cons
2 | ```scheme
3 | (cons first second)
4 | ```
5 | Returns a pair made of the two given values.
6 |
7 | ## Examples
8 | ```scheme
9 | (cons "RainLisp" 2023)
10 | ```
11 | -> *("RainLisp" . 2023)*
12 |
13 | ```scheme
14 | (cons (cons 'Name "RainLisp") (cons 'Copyright 2023))
15 | ```
16 | -> *((Name . "RainLisp") Copyright . 2023)*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/datetime-to-string.md:
--------------------------------------------------------------------------------
1 | # datetime-to-string
2 | ```scheme
3 | (datetime-to-string datetime format)
4 | ```
5 | Converts a datetime to its equivalent string representation, using a specified format in [invariant](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture) culture.
6 |
7 | > *datetime* to convert.
8 |
9 | > *format* is a [standard](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings) or [custom](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings) date and time format string.
10 |
11 | ## Example
12 | ```scheme
13 | (datetime-to-string (make-datetime 2023 12 31 22 30 45 123) "yyyy-MM-dd HH:mm:ss.fff")
14 | ```
15 | -> *"2023-12-31 22:30:45.123"*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/day.md:
--------------------------------------------------------------------------------
1 | # day
2 | ```scheme
3 | (day datetime)
4 | ```
5 | Returns the day of the month of a given datetime value, expressed as a value between 1 and 31.
6 |
7 | ## Example
8 | ```scheme
9 | (day (make-date 2023 12 31))
10 | ```
11 | -> *31*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/days-diff.md:
--------------------------------------------------------------------------------
1 | # days-diff
2 | ```scheme
3 | (days-diff datetime-from datetime-to)
4 | ```
5 | Returns the number of days, which can be positive or negative, between two datetimes.
6 |
7 | > *datetime-from* is the datetime to subtract.
8 |
9 | > *datetime-to* is the datetime to subtract the other one from.
10 |
11 | ## Example
12 | ```scheme
13 | (days-diff (make-date 2023 12 1) (make-date 2023 12 31))
14 | ```
15 | -> *30*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/debug.md:
--------------------------------------------------------------------------------
1 | # debug
2 | ```scheme
3 | (debug primitive-value)
4 | ```
5 | Writes a primitive value to the trace listeners in the debug [listeners](https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/trace-listeners) collection. The format of the output is determined by the local culture. Its return value is unspecified.
6 |
7 | > *primitive-value* is either a boolean, number, string or datetime.
8 |
9 | ## Example
10 | ```scheme
11 | (debug "RainLisp")
12 | ```
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/display.md:
--------------------------------------------------------------------------------
1 | # display
2 | ```scheme
3 | (display primitive-value)
4 | ```
5 | Writes a primitive value to the standard output. The format of the output is determined by the local culture. Its return value is unspecified.
6 |
7 | > *primitive-value* is either a boolean, number, string or datetime.
8 |
9 | ## Example
10 | ```scheme
11 | (display "RainLisp")
12 | ```
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/divide.md:
--------------------------------------------------------------------------------
1 | # /
2 | ```scheme
3 | (/ num1 num2 . nums)
4 | ```
5 | Returns the result of dividing two or more numeric values. The division accumulates from left to right.
6 |
7 | ## Example
8 | ```scheme
9 | (/ 14 2 2)
10 | ```
11 | -> *3.5*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/equal.md:
--------------------------------------------------------------------------------
1 | # =
2 | ```scheme
3 | (= value1 value2)
4 | ```
5 | Determines if two values are equal. Primitive values like numbers, strings, booleans and datetimes are compared by value. All others are compared by reference.
6 |
7 | > In traditional Scheme LISP, there are two related primitives. *equal?* compares values and *eq?* compares references. RainLisp differentiates in this regard and encapsulates both with *=*.
8 |
9 | ## Examples
10 | ```scheme
11 | (= 12.5 12.5)
12 | ```
13 | -> *true*
14 |
15 | ```scheme
16 | (= true true)
17 | ```
18 | -> *true*
19 |
20 | ```scheme
21 | (= "rain" "rain")
22 | ```
23 | -> *true*
24 |
25 | ```scheme
26 | (= (make-date 2023 12 31) (make-date 2023 12 31))
27 | ```
28 | -> *true*
29 |
30 | ```scheme
31 | ; A lambda is a reference type and evaluates to a new user procedure.
32 | (= (lambda () 0) (lambda () 0))
33 | ```
34 | -> *false*
35 |
36 | ```scheme
37 | ; nil is a reference type but unique globally.
38 | (= nil nil)
39 | ```
40 | -> *true*
41 |
42 | ```scheme
43 | ; Quote symbols are reference types but unique in an evaluation session.
44 | (= 'rain 'rain)
45 | ```
46 | -> *true*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/error.md:
--------------------------------------------------------------------------------
1 | # error
2 | ```scheme
3 | (error primitive-value)
4 | ```
5 | Causes a user exception with a string representation of a primitive value to be thrown.
6 | A numeric primitive value is formatted using the invariant culture but all other primitives use the local culture.
7 |
8 | > *primitive-value* is either a boolean, number, string or datetime.
9 |
10 | ## Example
11 | ```scheme
12 | (error "An error occured.")
13 | ```
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/eval.md:
--------------------------------------------------------------------------------
1 | # eval
2 | ```scheme
3 | (eval quote-symbol)
4 | ```
5 | Returns a result by evaluating a quote symbol as user code.
6 |
7 | ```scheme
8 | (eval quote-symbols-list)
9 | ```
10 | Returns a result by evaluating a non-empty list of quote symbols as user code.
11 |
12 | ## Examples
13 | ```scheme
14 | (define a 12)
15 | (eval 'a)
16 | ```
17 | -> *12*
18 |
19 | ```scheme
20 | (define a 1)
21 | (eval '(begin (set! a (+ a 1)) a))
22 | ```
23 | -> *2*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/floor.md:
--------------------------------------------------------------------------------
1 | # floor
2 | ```scheme
3 | (floor num)
4 | ```
5 | Rounds a numeric value to the largest integral that is less than or equal to it.
6 |
7 | > *num* is a numeric value to round.
8 |
9 | ## Examples
10 | ```scheme
11 | (floor 231.23456)
12 | ```
13 | -> *231*
14 |
15 | ```scheme
16 | (floor 231.56789)
17 | ```
18 | -> *231*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/greater-or-equal.md:
--------------------------------------------------------------------------------
1 | # >=
2 | ```scheme
3 | (>= num1 num2)
4 | ```
5 | Determines if the first numeric value is greater than or equal to the second one.
6 |
7 | ```scheme
8 | (>= datetime1 datetime2)
9 | ```
10 | Determines if the first datetime is the same as or later than the second one, ignoring time zones.
11 |
12 | ## Examples
13 | ```scheme
14 | (>= 7 4)
15 | ```
16 | -> *true*
17 |
18 | ```scheme
19 | (>= (make-date 2022 12 31) (make-date 2023 12 31))
20 | ```
21 | -> *false*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/greater.md:
--------------------------------------------------------------------------------
1 | # >
2 | ```scheme
3 | (> num1 num2)
4 | ```
5 | Determines if the first numeric value is greater than the second one.
6 |
7 | ```scheme
8 | (> datetime1 datetime2)
9 | ```
10 | Determines if the first datetime is later than the second one, ignoring time zones.
11 |
12 | ## Examples
13 | ```scheme
14 | (> 7 4)
15 | ```
16 | -> *true*
17 |
18 | ```scheme
19 | (> (make-date 2022 12 31) (make-date 2023 12 31))
20 | ```
21 | -> *false*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/hour.md:
--------------------------------------------------------------------------------
1 | # hour
2 | ```scheme
3 | (hour datetime)
4 | ```
5 | Returns the hour of a given datetime value, expressed as a value between 0 and 23.
6 |
7 | ## Example
8 | ```scheme
9 | (hour (make-datetime 2023 12 31 23 59 59 999))
10 | ```
11 | -> *23*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/hours-diff.md:
--------------------------------------------------------------------------------
1 | # hours-diff
2 | ```scheme
3 | (hours-diff datetime-from datetime-to)
4 | ```
5 | Returns the number of hours, ranging from -23 through 23, between the times of two datetimes.
6 |
7 | > *datetime-from* is the datetime to subtract.
8 |
9 | > *datetime-to* is the datetime to subtract the other one from.
10 |
11 | ## Example
12 | ```scheme
13 | (hours-diff (make-datetime 2023 12 30 20 0 0 0) (make-datetime 2023 12 31 22 0 0 0))
14 | ```
15 | -> *2*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/index-of-string.md:
--------------------------------------------------------------------------------
1 | # index-of-string
2 | ```scheme
3 | (index-of-string str value start-index)
4 | ```
5 | Returns the zero-based index of the first occurence of a string withing another string. The search starts at a specified character position.
6 | If the string is not found, -1 is returned. If the string to look for is empty, the return value is the start index.
7 |
8 | > *str* is the string to search in.
9 |
10 | > *value* is the string to look for.
11 |
12 | > *start-index* is the search starting position. Note that only its integral part is considered.
13 |
14 | ## Example
15 | ```scheme
16 | (index-of-string "RainLisp" "Lisp" 0)
17 | ```
18 | -> *4*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/is-null.md:
--------------------------------------------------------------------------------
1 | # null?
2 | ```scheme
3 | (null? value)
4 | ```
5 | Determines if the given value is nil, i.e. an empty list.
6 |
7 | ## Examples
8 | ```scheme
9 | (null? nil)
10 | ```
11 | -> *true*
12 |
13 | ```scheme
14 | (null? (list))
15 | ```
16 | -> *true*
17 |
18 | ```scheme
19 | (null? '())
20 | ```
21 | -> *true*
22 |
23 | ```scheme
24 | (null? (list 1 2 3))
25 | ```
26 | -> *false*
27 |
28 | ```scheme
29 | (null? 1)
30 | ```
31 | -> *false*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/is-pair.md:
--------------------------------------------------------------------------------
1 | # pair?
2 | ```scheme
3 | (pair? value)
4 | ```
5 | Determines if the given value is a pair.
6 |
7 | ## Examples
8 | ```scheme
9 | (pair? (cons 1 2))
10 | ```
11 | -> *true*
12 |
13 | ```scheme
14 | (pair? 1)
15 | ```
16 | -> *false*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/is-utc.md:
--------------------------------------------------------------------------------
1 | # utc?
2 | ```scheme
3 | (utc? datetime)
4 | ```
5 | Determines if the given datetime is Coordinated Universal Time (UTC).
6 |
7 | ## Examples
8 | ```scheme
9 | (utc? (utc-now))
10 | ```
11 | -> *true*
12 |
13 | ```scheme
14 | (utc? (now))
15 | ```
16 | -> *false*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/less-or-equal.md:
--------------------------------------------------------------------------------
1 | # <=
2 | ```scheme
3 | (<= num1 num2)
4 | ```
5 | Determines if the first numeric value is less than or equal to the second one.
6 |
7 | ```scheme
8 | (<= datetime1 datetime2)
9 | ```
10 | Determines if the first datetime is the same as or earlier than the second one, ignoring time zones.
11 |
12 | ## Examples
13 | ```scheme
14 | (<= 7 4)
15 | ```
16 | -> *false*
17 |
18 | ```scheme
19 | (<= (make-date 2022 12 31) (make-date 2023 12 31))
20 | ```
21 | -> *true*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/less.md:
--------------------------------------------------------------------------------
1 | # <
2 | ```scheme
3 | (< num1 num2)
4 | ```
5 | Determines if the first numeric value is less than the second one.
6 |
7 | ```scheme
8 | (< datetime1 datetime2)
9 | ```
10 | Determines if the first datetime is earlier than the second one, ignoring time zones.
11 |
12 | ## Examples
13 | ```scheme
14 | (< 7 4)
15 | ```
16 | -> *false*
17 |
18 | ```scheme
19 | (< (make-date 2022 12 31) (make-date 2023 12 31))
20 | ```
21 | -> *true*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/list.md:
--------------------------------------------------------------------------------
1 | # list
2 | ```scheme
3 | (list . values)
4 | ```
5 | Returns a new list made of the values provided, or nil if none is given.
6 |
7 | ## Examples
8 | ```scheme
9 | (list "RainLisp" 2023 true)
10 | ```
11 | -> *("RainLisp" 2023 true)*
12 |
13 | ```scheme
14 | ; Returns nil, i.e. the empty list.
15 | (list)
16 | ```
17 | -> *()*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/make-date.md:
--------------------------------------------------------------------------------
1 | # make-date
2 | ```scheme
3 | (make-date year month day)
4 | ```
5 | Returns a new datetime value in an unspecified time zone, made of a year, month and day of the month.
6 |
7 | > *year* (1 through 9999).
8 |
9 | > *month* (1 through 12).
10 |
11 | > *day* (1 through the number of days in month).
12 |
13 | Note that only the integral part of the arguments is considered.
14 |
15 | ## Example
16 | ```scheme
17 | (make-date 2023 12 31)
18 | ```
19 | -> *2023-12-31 00:00:00.000*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/make-datetime.md:
--------------------------------------------------------------------------------
1 | # make-datetime
2 | ```scheme
3 | (make-datetime year month day hour minute second millisecond)
4 | ```
5 | Returns a new datetime value in an unspecified time zone, made of a year, month, day of the month, hour, minute, second and millisecond.
6 |
7 | > *year* (1 through 9999).
8 |
9 | > *month* (1 through 12).
10 |
11 | > *day* (1 through the number of days in month).
12 |
13 | > *hour* (0 through 23).
14 |
15 | > *minute* (0 through 59).
16 |
17 | > *second* (0 through 59).
18 |
19 | > *millisecond* (0 through 999).
20 |
21 | Note that only the integral part of the arguments is considered.
22 |
23 | ## Example
24 | ```scheme
25 | (make-datetime 2023 12 31 23 59 59 999)
26 | ```
27 | -> *2023-12-31 23:59:59.999*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/millisecond.md:
--------------------------------------------------------------------------------
1 | # millisecond
2 | ```scheme
3 | (millisecond datetime)
4 | ```
5 | Returns the millisecond of a given datetime value, expressed as a value between 0 and 999.
6 |
7 | ## Example
8 | ```scheme
9 | (millisecond (make-datetime 2023 12 31 23 59 30 123))
10 | ```
11 | -> *123*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/milliseconds-diff.md:
--------------------------------------------------------------------------------
1 | # milliseconds-diff
2 | ```scheme
3 | (milliseconds-diff datetime-from datetime-to)
4 | ```
5 | Returns the number of milliseconds, ranging from -999 through 999, between the times of two datetimes.
6 |
7 | > *datetime-from* is the datetime to subtract.
8 |
9 | > *datetime-to* is the datetime to subtract the other one from.
10 |
11 | ## Example
12 | ```scheme
13 | (milliseconds-diff (make-datetime 2023 12 30 20 35 20 100) (make-datetime 2023 12 31 22 55 59 888))
14 | ```
15 | -> *788*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/minus.md:
--------------------------------------------------------------------------------
1 | # -
2 | ```scheme
3 | (- num1 num2 . nums)
4 | ```
5 | Returns the result of subtracting two or more numeric values. The subtraction accumulates from left to right.
6 |
7 | ## Example
8 | ```scheme
9 | (- 9 5 3 1)
10 | ```
11 | -> *0*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/minute.md:
--------------------------------------------------------------------------------
1 | # minute
2 | ```scheme
3 | (minute datetime)
4 | ```
5 | Returns the minute of a given datetime value, expressed as a value between 0 and 59.
6 |
7 | ## Example
8 | ```scheme
9 | (minute (make-datetime 2023 12 31 23 59 30 123))
10 | ```
11 | -> *59*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/minutes-diff.md:
--------------------------------------------------------------------------------
1 | # minutes-diff
2 | ```scheme
3 | (minutes-diff datetime-from datetime-to)
4 | ```
5 | Returns the number of minutes, ranging from -59 through 59, between the times of two datetimes.
6 |
7 | > *datetime-from* is the datetime to subtract.
8 |
9 | > *datetime-to* is the datetime to subtract the other one from.
10 |
11 | ## Example
12 | ```scheme
13 | (minutes-diff (make-datetime 2023 12 30 20 35 0 0) (make-datetime 2023 12 31 22 55 0 0))
14 | ```
15 | -> *20*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/modulo.md:
--------------------------------------------------------------------------------
1 | # %
2 | ```scheme
3 | (% num1 num2 . nums)
4 | ```
5 | Returns the result of calculating the modulo of two or more numeric values. The operation accumulates from left to right.
6 |
7 | ## Example
8 | ```scheme
9 | (% 7 4 2)
10 | ```
11 | -> *1*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/month.md:
--------------------------------------------------------------------------------
1 | # month
2 | ```scheme
3 | (month datetime)
4 | ```
5 | Returns the month of a given datetime value, expressed as a value between 1 and 12.
6 |
7 | ## Example
8 | ```scheme
9 | (month (make-date 2023 12 31))
10 | ```
11 | -> *12*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/multiply.md:
--------------------------------------------------------------------------------
1 | # *
2 | ```scheme
3 | (* num1 num2 . nums)
4 | ```
5 | Returns the result of multiplying two or more numeric values.
6 |
7 | ## Example
8 | ```scheme
9 | (* 9 5 3 1)
10 | ```
11 | -> *135*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/newline.md:
--------------------------------------------------------------------------------
1 | # newline
2 | ```scheme
3 | (newline)
4 | ```
5 | Writes a new line to the standard output. Its return value is unspecified.
6 |
7 | ## Example
8 | ```scheme
9 | (newline)
10 | ```
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/nil.md:
--------------------------------------------------------------------------------
1 | # nil
2 | ```scheme
3 | nil
4 | ```
5 | Returns the empty list. The empty list is a reference type and unique in a system wide scope.
6 | It also serves as list termination.
7 |
8 | ## Examples
9 | ```scheme
10 | nil
11 | ```
12 | -> *()*
13 |
14 | ```scheme
15 | (= nil (list))
16 | ```
17 | -> *true*
18 |
19 | ```scheme
20 | (= nil '())
21 | ```
22 | -> *true*
23 |
24 | ```scheme
25 | (null? nil)
26 | ```
27 | -> *true*
28 |
29 | ```scheme
30 | (= nil 1)
31 | ```
32 | -> *false*
33 |
34 | ```scheme
35 | (cons 1 (cons 2 (cons 3 nil)))
36 | ```
37 | -> *(1 2 3)*
38 |
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/not.md:
--------------------------------------------------------------------------------
1 | # not
2 | ```scheme
3 | (not value)
4 | ```
5 | Returns the logical negation of a value. Every value is true except explicit false.
6 |
7 | ## Examples
8 | ```scheme
9 | (not false)
10 | ```
11 | -> *true*
12 |
13 | ```scheme
14 | (not 7)
15 | ```
16 | -> *false*
17 |
18 | ```scheme
19 | (not "rain")
20 | ```
21 | -> *false*
22 |
23 | ```scheme
24 | (not (lambda () 0))
25 | ```
26 | -> *false*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/now.md:
--------------------------------------------------------------------------------
1 | # now
2 | ```scheme
3 | (now)
4 | ```
5 | Returns the current date and time on this computer, expressed as the local time.
6 |
7 | ## Example
8 | ```scheme
9 | (now)
10 | ```
11 | -> *2023-03-30 20:34:36.531*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/number-to-string.md:
--------------------------------------------------------------------------------
1 | # number-to-string
2 | ```scheme
3 | (number-to-string num format)
4 | ```
5 | Converts a numeric value to its equivalent string representation, using a specified format in [invariant](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture) culture.
6 |
7 | > *num* is a numeric value to convert.
8 |
9 | > *format* is a numeric format string value. It can be a [standard](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings) or [custom](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings) format.
10 |
11 | ## Example
12 | ```scheme
13 | (number-to-string 23.4678 "000.000")
14 | ```
15 | -> *"023.468"*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/parse-datetime.md:
--------------------------------------------------------------------------------
1 | # parse-datetime
2 | ```scheme
3 | (parse-datetime str format)
4 | ```
5 | Converts a string representation of a datetime in [invariant](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture) culture to its datetime equivalent, using a specified format.
6 |
7 | > *str* is the string containing the datetime info.
8 |
9 | > *format* is a string specifying the exact format of the datetime info. It can be a [standard](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings) or [custom](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings) format.
10 |
11 | ## Example
12 | ```scheme
13 | (parse-datetime "2023-12-31 22:30:45.123" "yyyy-MM-dd HH:mm:ss.fff")
14 | ```
15 | -> *2023-12-31 22:30:45.123*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/parse-number-culture.md:
--------------------------------------------------------------------------------
1 | # parse-number-culture
2 | ```scheme
3 | (parse-number-culture str culture)
4 | ```
5 | Converts a string representation of a numeric value in a culture-specific format to its number equivalent.
6 |
7 | > *str* is the string containing the numeric info.
8 |
9 | > *culture* is a string specifying the culture name. If the culture name is an empty string, the [invariant](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture) culture is used.
10 | For a list of valid names, look at the "*Language tag*" column of the [language table](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c).
11 |
12 | ## Examples
13 | ```scheme
14 | (parse-number-culture "2345.6789" "en-EN")
15 | ```
16 | -> *2345.6789*
17 |
18 | ```scheme
19 | (parse-number-culture "2345,6789" "el-GR")
20 | ```
21 | -> *2345.6789*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/parse-number.md:
--------------------------------------------------------------------------------
1 | # parse-number
2 | ```scheme
3 | (parse-number str)
4 | ```
5 | Converts a string representation of a numeric value in [invariant](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture) culture to its number equivalent.
6 |
7 | ## Example
8 | ```scheme
9 | (parse-number "2345.6789")
10 | ```
11 | -> *2345.6789*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/plus.md:
--------------------------------------------------------------------------------
1 | # +
2 | ```scheme
3 | (+ num1 num2 . nums)
4 | ```
5 | Returns the sum of numeric values. It accepts two or more values.
6 |
7 | ```scheme
8 | (+ str1 str2 . strs)
9 | ```
10 | Returns the concatenation of string values. It accepts two or more values.
11 |
12 | ## Examples
13 | ```scheme
14 | (+ 1 2 3 4)
15 | ```
16 | -> *10*
17 |
18 | ```scheme
19 | (+ "Rain" "Lisp")
20 | ```
21 | -> *"RainLisp"*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/replace-string.md:
--------------------------------------------------------------------------------
1 | # replace-string
2 | ```scheme
3 | (replace-string str old-value new-value)
4 | ```
5 | Returns a new string in which all occurrences of a substring within a given string are replaced by another one.
6 | If the string to be replaced is not found, the original string is returned unchanged.
7 |
8 | > *str* is the string to search in.
9 |
10 | > *old-value* is the string to be replaced.
11 |
12 | > *new-value* is the string to replace all occurrences of the old value.
13 |
14 | ## Example
15 | ```scheme
16 | (replace-string "Scheme LISP" "Scheme" "Rain")
17 | ```
18 | -> *"Rain LISP"*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/round.md:
--------------------------------------------------------------------------------
1 | # round
2 | ```scheme
3 | (round num decimals)
4 | ```
5 | Rounds a numeric value to a specified number of fractional digits, using the away from zero rounding convention.
6 | If the given numeric value to round has fewer fractional digits than the one specified, it is returned unchanged.
7 |
8 | > *num* is a numeric value to round.
9 |
10 | > *decimals* is the number of decimal places in the return value (0 through 28).
11 |
12 | Note that only the integral part of decimal places is considered.
13 |
14 | ## Examples
15 | ```scheme
16 | (round 231.45478 2)
17 | ```
18 | -> *231.45*
19 |
20 | ```scheme
21 | (round 231.45578 2)
22 | ```
23 | -> *231.46*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/second.md:
--------------------------------------------------------------------------------
1 | # second
2 | ```scheme
3 | (second datetime)
4 | ```
5 | Returns the second of a given datetime value, expressed as a value between 0 and 59.
6 |
7 | ## Example
8 | ```scheme
9 | (second (make-datetime 2023 12 31 23 59 30 123))
10 | ```
11 | -> *30*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/seconds-diff.md:
--------------------------------------------------------------------------------
1 | # seconds-diff
2 | ```scheme
3 | (seconds-diff datetime-from datetime-to)
4 | ```
5 | Returns the number of seconds, ranging from -59 through 59, between the times of two datetimes.
6 |
7 | > *datetime-from* is the datetime to subtract.
8 |
9 | > *datetime-to* is the datetime to subtract the other one from.
10 |
11 | ## Example
12 | ```scheme
13 | (seconds-diff (make-datetime 2023 12 30 20 35 20 0) (make-datetime 2023 12 31 22 55 59 0))
14 | ```
15 | -> *39*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/set-car!.md:
--------------------------------------------------------------------------------
1 | # set-car!
2 | ```scheme
3 | (set-car! pair value)
4 | ```
5 | Sets the first part of a pair to the value provided. Its return value is unspecified.
6 |
7 | ## Example
8 | ```scheme
9 | (define a-pair (cons 1 1))
10 | (set-car! a-pair 0)
11 | a-pair
12 | ```
13 | -> *(0 . 1)*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/set-cdr!.md:
--------------------------------------------------------------------------------
1 | # set-cdr!
2 | ```scheme
3 | (set-cdr! pair value)
4 | ```
5 | Sets the second part of a pair to the value provided. Its return value is unspecified.
6 |
7 | ## Example
8 | ```scheme
9 | (define a-pair (cons 1 1))
10 | (set-cdr! a-pair 2)
11 | a-pair
12 | ```
13 | -> *(1 . 2)*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/string-length.md:
--------------------------------------------------------------------------------
1 | # string-length
2 | ```scheme
3 | (string-length str)
4 | ```
5 | Returns the length of a given string.
6 |
7 | ## Example
8 | ```scheme
9 | (string-length "RainLisp")
10 | ```
11 | -> *8*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/substring.md:
--------------------------------------------------------------------------------
1 | # substring
2 | ```scheme
3 | (substring str start-index length)
4 | ```
5 | Returns a substring value of a given string. The substring starts at a specified character position and has a specified length.
6 | An empty string is returned if the start index is equal to the length of the string and the desired length is zero.
7 |
8 | > *str* is the string to get a substring from.
9 |
10 | > *start-index* is the zero-based start index.
11 |
12 | > *length* is the length of the substring.
13 |
14 | Note that only the integral part of the numeric arguments is considered.
15 |
16 | > Note that in traditional LISP, the last parameter is not the length but a stop index. RainLisp differentiates in this regard.
17 |
18 | ## Example
19 | ```scheme
20 | (substring "RainLisp" 0 4)
21 | ```
22 | -> *"Rain"*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/to-local.md:
--------------------------------------------------------------------------------
1 | # to-local
2 | ```scheme
3 | (to-local datetime)
4 | ```
5 | Converts a Universal Coordinated Time (UTC) datetime value to local. It must be a UTC or unspecified datetime, in which case it is treated as UTC.
6 |
7 | ## Example
8 | ```scheme
9 | (to-local (make-datetime 2023 3 30 20 07 20 123))
10 | ```
11 | -> *2023-03-30 23:07:20.123*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/to-lower.md:
--------------------------------------------------------------------------------
1 | # to-lower
2 | ```scheme
3 | (to-lower str)
4 | ```
5 | Returns a copy of a string value converted to lower case using the casing rules of the [invariant](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture) culture.
6 |
7 | ## Example
8 | ```scheme
9 | (to-lower "RAIN")
10 | ```
11 | -> *"rain"*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/to-upper.md:
--------------------------------------------------------------------------------
1 | # to-upper
2 | ```scheme
3 | (to-upper str)
4 | ```
5 | Returns a copy of a string value converted to upper case using the casing rules of the [invariant](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture) culture.
6 |
7 | ## Example
8 | ```scheme
9 | (to-upper "rain")
10 | ```
11 | -> *"RAIN"*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/to-utc.md:
--------------------------------------------------------------------------------
1 | # to-utc
2 | ```scheme
3 | (to-utc datetime)
4 | ```
5 | Converts a local datetime value to Universal Coordinated Time (UTC). It must be a local or unspecified datetime, in which case it is treated as local.
6 |
7 | ## Example
8 | ```scheme
9 | (to-utc (make-datetime 2023 3 30 21 07 20 123))
10 | ```
11 | -> *2023-03-30 18:07:20.123*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/trace.md:
--------------------------------------------------------------------------------
1 | # trace
2 | ```scheme
3 | (trace primitive-value)
4 | ```
5 | Writes a primitive value to the trace listeners in the trace [listeners](https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/trace-listeners) collection. The format of the output is determined by the local culture. Its return value is unspecified.
6 |
7 | > *primitive-value* is either a boolean, number, string or datetime.
8 |
9 | ## Example
10 | ```scheme
11 | (trace "RainLisp")
12 | ```
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/utc-now.md:
--------------------------------------------------------------------------------
1 | # utc-now
2 | ```scheme
3 | (utc-now)
4 | ```
5 | Returns the current date and time on this computer, expressed as the Coordinated Universal Time (UTC).
6 |
7 | ## Example
8 | ```scheme
9 | (utc-now)
10 | ```
11 | -> *2023-03-30 17:37:05.693*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/xor.md:
--------------------------------------------------------------------------------
1 | # xor
2 | ```scheme
3 | (xor value1 value2 . values)
4 | ```
5 | Returns the result of calculating the logical xor of two or more values. The operation accumulates from left to right.
6 |
7 | ## Example
8 | ```scheme
9 | (xor true true false)
10 | ```
11 | -> *false*
--------------------------------------------------------------------------------
/RainLisp/Docs/primitives/year.md:
--------------------------------------------------------------------------------
1 | # year
2 | ```scheme
3 | (year datetime)
4 | ```
5 | Returns the year of a given datetime value, expressed as a value between 1 and 9999.
6 |
7 | ## Example
8 | ```scheme
9 | (year (make-date 2023 12 31))
10 | ```
11 | -> *2023*
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/advanced-data-structures.md:
--------------------------------------------------------------------------------
1 | # Advanced Data Structures
2 | As mentioned before, someone can create many elaborate data structures with just a simple building block, the simple and humble pair.
3 |
4 | Later, when we talk about data-directed programming, we will create a two-dimensional lookup table, where each value
5 | is indexed based on two keys.
6 |
7 | For now, you can refer to SICP and see how a [queue](https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/full-text/book/book-Z-H-22.html#%_sec_3.3.2)
8 | can be implemented.
9 |
10 | You can also have a look at [sets](https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/full-text/book/book-Z-H-16.html#%_sec_2.3.3),
11 | which are collections of distinct objects.
12 |
13 | Next, let's move on to [message passing](message-passing.md).
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/begin.md:
--------------------------------------------------------------------------------
1 | # Begin Code Block
2 | With `begin`, you can define a group of expressions to be evaluated in sequence.
3 | Its result is the last expression's result.
4 |
5 | ```scheme
6 | (begin
7 | (display 1)
8 | (display 2)
9 | (display 3))
10 | ```
11 | -> *123*
12 |
13 | This example writes `1`, `2` and `3` consecutively to the standard output.
14 |
15 | Let's see another one.
16 |
17 | ```scheme
18 | (+ 1
19 | (begin
20 | (display "About to return 3 which will be added to 1.")
21 | (newline)
22 | 3))
23 | ```
24 | ->
25 | ```
26 | About to return 3 which will be added to 1.
27 | 4
28 | ```
29 |
30 | As you can see, `begin` writes a string to the standard output and evaluates to `3`,
31 | which is then added to `1` giving `4`.
32 |
33 | You may want to see more examples of [begin](../special-forms-derived-expressions/begin.md).
34 |
35 | Next, let's dive deeper with [conditionals](conditionals.md).
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/booleans.md:
--------------------------------------------------------------------------------
1 | # Booleans
2 | Booleans is another RainLisp's basic data type. A boolean is either `true` or `false`.
3 |
4 | Let's evaluate some boolean literals.
5 |
6 | ```scheme
7 | true
8 | ```
9 | -> *true*
10 |
11 | ```scheme
12 | false
13 | ```
14 | -> *false*
15 |
16 | There is a primitive procedure `not` that returns the logical negation of the argument.
17 |
18 | ```scheme
19 | (not true)
20 | ```
21 | -> *false*
22 |
23 | ```scheme
24 | (not false)
25 | ```
26 | -> *true*
27 |
28 | > Note that in RainLisp, in conditional expressions like `if`, `cond` and others like `not`, `and`, `or` that expect booleans,
29 | all values other than false are considered to be true. For example, `(not 0)` and `(not 1)` both give `false`.
30 |
31 | The boolean logical operations are:
32 | - [and](../special-forms-derived-expressions/and.md)
33 | - [not](../primitives/not.md)
34 | - [or](../special-forms-derived-expressions/or.md)
35 | - [xor](../primitives/xor.md)
36 |
37 | Next, let's learn about [strings](strings.md).
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/comment.md:
--------------------------------------------------------------------------------
1 | # Comment
2 | It's often useful to complement your code with additional explanatory information in natural language.
3 | In RainLisp, you can start a comment with the semicolon character `;`.
4 | Once started, a comment stops at the end of the line.
5 |
6 | Let's write some comment.
7 |
8 | ```scheme
9 | ; This is a comment occupying the whole line on its own.
10 | (+ 1 1) ; Add two numbers. This is a comment next to some code.
11 | ```
12 | -> *2*
13 |
14 | > Note that in RainLisp, there is no alternative way to write comment.
15 | For example, there is no block comment construct.
16 | If you want to comment a group of lines, each should start with a semicolon.
17 |
18 | Next, let's see how to define a block of code with [begin](begin.md).
19 |
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/img/1d-table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/RainLisp/Docs/quick-start/img/1d-table.png
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/img/2d-table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/RainLisp/Docs/quick-start/img/2d-table.png
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/img/complex-pair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/RainLisp/Docs/quick-start/img/complex-pair.png
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/img/list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/RainLisp/Docs/quick-start/img/list.png
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/img/simple-pair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chr1st0scli/RainLisp/84893acfaaf0422577d6464143f320fdde0bff2d/RainLisp/Docs/quick-start/img/simple-pair.png
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/let.md:
--------------------------------------------------------------------------------
1 | # Let Code Block
2 | The `let` keyword defines a block of code in a scope or context if you will, where some variables are only visible
3 | within it.
4 |
5 | Let's see an example.
6 |
7 | ```scheme
8 | (let ((a 1) (b 2))
9 | (+ a b))
10 | ```
11 | -> *3*
12 |
13 | We have easily defined two variables `a` and `b` in one line and some code that uses them. The two variables
14 | are only visible within the let expression.
15 |
16 | Let's see another one.
17 |
18 | ```scheme
19 | (define (get-length) 10)
20 | (define (get-height) 22)
21 | (define (get-breadth) 45)
22 |
23 | (let ((x (get-length))
24 | (y (get-height))
25 | (z (get-breadth)))
26 | (define product (* x y z))
27 | (debug "The volume of the cuboid is: ")
28 | (debug product)
29 | product)
30 | ```
31 | -> *9900*
32 |
33 | We define three procedures that supposedly give the dimensions of a cuboid.
34 | We then use a `let` expression where we call the procedures and assign the results to three variables
35 | `x`, `y` and `z`, representing the cuboid's dimensions. Then, in the `let` body, we define yet another variable
36 | that is the product of the former three.
37 |
38 | The expressions in the body are executed in turn. Firstly, we are using the [debug](../primitives/debug.md)
39 | primitive procedure to write a log message. The last expression gives the result of the `let` itself.
40 |
41 | > Like in a procedure, you can only use the `define` keyword at the start of the `let`'s body.
42 | This is because `let` is syntactic sugar for a procedure call. If you want to see more
43 | details about this, see the technical [specification](../special-forms-derived-expressions/let.md).
44 |
45 | Now, let's end the language basics with [quotes](quotes.md).
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/message-passing.md:
--------------------------------------------------------------------------------
1 | # Message Passing
2 | Suppose that you want to write a procedure that does different things based on a criterion. That criterion is an argument passed
3 | to the procedure and can be seen as a message, hence the message passing term.
4 |
5 | Assume that we want to define a procedure that squares the result of a numeric operation on two numbers.
6 |
7 | ```scheme
8 | (define (op-squared op x y)
9 |
10 | (define (square n)
11 | (* n n))
12 |
13 | (define proc (cond ((= op '+) +)
14 | ((= op '-) -)
15 | ((= op '*) *)
16 | ((= op '/) /)
17 | (else (error "Unsupported operation."))))
18 |
19 | (square (proc x y)))
20 |
21 | (op-squared '+ 8 4)
22 | (op-squared '- 8 4)
23 | (op-squared '* 8 4)
24 | (op-squared '/ 8 4)
25 | ```
26 | ->
27 | ```
28 | 144
29 | 16
30 | 1024
31 | 4
32 | ```
33 |
34 | Above, we define the local `square` procedure that squares a number. We also define a local variable `proc` which we assign a numeric primitive procedure to,
35 | based on the message `op` we receive from the caller. Then, we apply the correct primitive procedure to `x` and `y` and square the result to get the final one.
36 |
37 | > Quote symbols are a perfect match for message passing, because they are descriptive and fast to compare. Recall that when quote
38 | symbols are tested for equality, only their memory addresses are compared.
39 |
40 | We will later take this technique further and see how it can be used in other disciplines, like encapsulation and data directed programming.
41 |
42 | Let's move on to [encapsulation](encapsulation.md) for now.
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/metaprogramming.md:
--------------------------------------------------------------------------------
1 | # Metaprogramming
2 | Have you ever wondered if it is possible to write a program that can write another one?
3 |
4 | The answer is yes. We are going to investigate yet another aspect of quote symbols, that enables us to generate code and use
5 | the [eval](../primitives/eval.md) primitive procedure to evalute it.
6 |
7 | We will use an example that might not be realistic or make a lot of sense, just for illustration purposes.
8 | Let's define a procedure that creates code that counts up to a given number.
9 |
10 | ```scheme
11 | ; Procedure that builds code that counts.
12 | (define (build-counting-code count)
13 | (define (iter quote-list cnt)
14 | (if (= cnt count)
15 | (append quote-list '(a)) ; In the end, return a.
16 | (iter (append quote-list '((set! a (+ a 1)))) (+ cnt 1)))) ; Append successive assignments to a, incremented by one.
17 |
18 | ; Start with a lambda that defines variable a that is set to 0.
19 | (iter '(lambda () (define a 0)) 0))
20 |
21 | (define code (build-counting-code 4))
22 |
23 | ; A list of quote symbols.
24 | code
25 |
26 | ; Evaluating code, gives a lambda as defined above.
27 | (define count-proc (eval code))
28 |
29 | (count-proc)
30 | ```
31 | ->
32 | ```
33 | (lambda () (define a 0) (set! a (+ a 1)) (set! a (+ a 1)) (set! a (+ a 1)) (set! a (+ a 1)) a)
34 | 4
35 | ```
36 |
37 | We call the procedure `build-counting-code` with `4` as an argument. As a result, the source code of a lambda
38 | that counts up to four, is generated and assigned to `code`. This is in the form of a list of quote symbols.
39 |
40 | We then provide this list to the `eval` primitive procedure and the code is executed, thus creating a user procedure
41 | which is assigned to `count-proc`.
42 |
43 | Finally, we execute it and enjoy the fruits of our labor.
44 |
45 | Let's move on to the final section and see some more [looping techniques](cps.md).
46 |
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/numbers.md:
--------------------------------------------------------------------------------
1 | # Numbers
2 | Numbers is one of the basic data types of RainLisp.
3 | You can specify a number with an optional number sign, some digits and optionally decimal digits.
4 |
5 | Let's try evaluating some numbers.
6 |
7 | ```scheme
8 | 12
9 | ```
10 | -> *12*
11 |
12 | ```scheme
13 | +12.34
14 | ```
15 | -> *12.34*
16 |
17 | ```scheme
18 | -12.34
19 | ```
20 | -> *-12.34*
21 |
22 | > Note that under the hood, all RainLisp numbers are 64-bit floating point, which reminds the way Javascript treats them.
23 |
24 | You can do all the typical operations on numbers that you are already familiar with.
25 | Let's add some.
26 |
27 | ```scheme
28 | (+ 1 2 3 4)
29 | ```
30 | -> *10*
31 |
32 | > Note that RainLisp, being a LISP dialect, uses prefix notation instead of infix.
33 | I.e. instead of `1 + 2 + 3 + 4`, you specify the + operator once, followed by the operands
34 | and surround everything with parentheses like so: `(+ 1 2 3 4)`.
35 |
36 | Let's subtract some numbers.
37 |
38 | ```scheme
39 | (- 10 5.5)
40 | ```
41 | -> *4.5*
42 |
43 | The operations that relate to numbers are:
44 |
45 | - [+](../primitives/plus.md)
46 | - [-](../primitives/minus.md)
47 | - [*](../primitives/multiply.md)
48 | - [/](../primitives/divide.md)
49 | - [%](../primitives/modulo.md)
50 | - [<](../primitives/less.md)
51 | - [<=](../primitives/less-or-equal.md)
52 | - [=](../primitives/equal.md)
53 | - [>](../primitives/greater.md)
54 | - [>=](../primitives/greater-or-equal.md)
55 | - [ceiling](../primitives/ceiling.md)
56 | - [floor](../primitives/floor.md)
57 | - [number-to-string](../primitives/number-to-string.md)
58 | - [parse-number](../primitives/parse-number.md)
59 | - [parse-number-culture](../primitives/parse-number-culture.md)
60 | - [round](../primitives/round.md)
61 |
62 | Next, let's learn about [booleans](booleans.md).
63 |
--------------------------------------------------------------------------------
/RainLisp/Docs/quick-start/quotes.md:
--------------------------------------------------------------------------------
1 | # Quotes
2 | You can imagine that a quote is something like a tag that you may attach to data.
3 | It is a feature that opens the doors to many possibilities. You can use them with
4 | user data structures, in message passing, data driven programming and metaprogramming
5 | that we will see later.
6 |
7 | For now, let's just introduce the topic.
8 |
9 | ```scheme
10 | (quote this-is-a-quote)
11 | ```
12 | -> *this-is-a-quote*
13 |
14 | The above expression creates the quote symbol `this-is-a-quote`.
15 |
16 | Traditionally in LISP dialects, there is an alternative way to create quotes,
17 | using the single quote character `'`. It is often preferred for its convenience.
18 | Generally, `'abc` is equivalent to `(quote abc)`.
19 |
20 | ```scheme
21 | 'this-is-a-quote
22 | ```
23 | -> *this-is-a-quote*
24 |
25 | A quote symbol is unique during an evaluation session, so it comes in handy for equality checks.
26 | For example, we can check if something is tagged with a particular text.
27 |
28 | > The comparisons are also performant, because quotes are reference types, which means that only
29 | memory addresses are compared.
30 |
31 | ```scheme
32 | (= 'this-is-a-quote 'this-is-a-quote)
33 | ```
34 | -> *true*
35 |
36 | Also, they are case sensitive.
37 |
38 | ```scheme
39 | (= 'this-is-a-quote 'This-is-a-quote)
40 | ```
41 | -> *false*
42 |
43 | You can also create lists of quotes.
44 |
45 | ```scheme
46 | '(ab cd 10 20 30)
47 | ```
48 | -> *(ab cd 10 20 30)*
49 |
50 | or equivalently
51 |
52 | ```scheme
53 | (quote (ab cd 10 20 30))
54 | ```
55 | -> *(ab cd 10 20 30)*
56 |
57 | > Something notable is that a quote of a primitive literal in RainLisp is just a quote.
58 | For example `'10` is the quote symbol `10` and cannot be handled like a number.
59 | Whereas in other LISP dialects, it can. You can add it or do anything to it that you can to numbers.
60 | In RainLisp, once a quote, always a quote.
61 |
62 | If you want to see more examples, look at the [specification](../special-forms-derived-expressions/quote.md).
63 |
64 | Congratulations! You have covered all the basics of RainLisp.
65 | It's time to move on to [data structures](pairs.md).
66 |
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions.md:
--------------------------------------------------------------------------------
1 | # Special Forms & Derived Expressions
2 |
3 | Special forms are reserved keywords with special language semantics. Derived expressions are
4 | syntactic sugar, i.e. reserved keywords that are transformed to equivalent special forms.
5 |
6 | - [and](special-forms-derived-expressions/and.md)
7 | - [begin](special-forms-derived-expressions/begin.md)
8 | - [cond](special-forms-derived-expressions/cond.md)
9 | - [cons-stream](special-forms-derived-expressions/cons-stream.md)
10 | - [define](special-forms-derived-expressions/define.md)
11 | - [delay](special-forms-derived-expressions/delay.md)
12 | - [if](special-forms-derived-expressions/if.md)
13 | - [lambda](special-forms-derived-expressions/lambda.md)
14 | - [let](special-forms-derived-expressions/let.md)
15 | - [or](special-forms-derived-expressions/or.md)
16 | - [procedure application](special-forms-derived-expressions/function-application.md)
17 | - [quote](special-forms-derived-expressions/quote.md)
18 | - [set!](special-forms-derived-expressions/set!.md)
19 |
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/and.md:
--------------------------------------------------------------------------------
1 | # and
2 | A derived expression that implements a logical and. It accepts at least one expression.
3 | ```
4 | (and expression . expressions)
5 | ```
6 | Each expression is evaluated from left to right, until one evaluates to false or the last expression is reached, in which case it is the result of the evaluation.
7 |
8 | ## Examples
9 | ```scheme
10 | (and true true true)
11 | ```
12 | -> *true*
13 |
14 | ```scheme
15 | (and true false true)
16 | ```
17 | -> *false*
18 |
19 | ```scheme
20 | (and (> 1 0) (> 2 1) (> 3 2))
21 | ```
22 | -> *true*
23 |
24 | ```scheme
25 | (and (> 1 0) (< 2 1) (> 3 2))
26 | ```
27 | -> *false*
28 |
29 | ## Remarks
30 | > `and` is syntactic sugar for a nested `if`.
31 |
32 | > Note that in traditional LISP `(and)` with no operands, evaluates to `true`. RainLisp differentiates in this regard.
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/begin.md:
--------------------------------------------------------------------------------
1 | # begin
2 | A special form for defining a block of expressions to evaluate in the order they appear.
3 | ```
4 | (begin expression . expressions)
5 | ```
6 | It accepts at least one expression and the evaluation result of the `begin` itself, is the last expression's result.
7 |
8 | ## Example
9 | ```scheme
10 | ; Define a variable.
11 | (define a 1)
12 | ; Evaluate a code block.
13 | (begin
14 | (set! a (+ a 1))
15 | (set! a (+ a 1))
16 | (set! a (+ a 1))
17 | a)
18 | ```
19 | -> *4*
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/cond.md:
--------------------------------------------------------------------------------
1 | # cond
2 | A derived expression for declaring many alternative expressions to be evaluated based on the result of different predicates.
3 | This is typically known as an `if... else if... else...` expression.
4 | It has one or more conditional clauses, the `(predicate expression . expressions)` part, followed by an optional conditional else clause in the end.
5 | ```
6 | (cond (predicate expression . expressions) (else expression . expressions))
7 | ```
8 |
9 | The first expression of a conditional clause is the predicate. If it evaluates to true, the rest of the expressions
10 | will be evaluated in turn and the last one's result will be the final one. If the predicates of all conditional clauses evaluate to false, the
11 | conditional else clause is evaluated. The expressions are once again evaluated in the order they appear and the last one's result is the final one.
12 | If no conditional else clause is provided, the final result is unspecified.
13 |
14 | ## Examples
15 | ```scheme
16 | ; Define a variable.
17 | (define x 0)
18 | ; Evaluate a condition.
19 | (cond ((< x 0) "negative")
20 | ((= x 0) "zero")
21 | (else "positive"))
22 | ```
23 | -> *"zero"*
24 |
25 | ```scheme
26 | ; Define a variable.
27 | (define x 3)
28 |
29 | ; Print a description and a new line and return 0 for zero, -1 for a negative value and 1 for a positive one.
30 | (cond ((< x 0)
31 | (display "negative")
32 | (newline)
33 | -1)
34 | ((= x 0)
35 | (display "zero")
36 | (newline)
37 | 0)
38 | (else
39 | (display "positive")
40 | (newline)
41 | 1))
42 | ```
43 | ->
44 | ```
45 | positive
46 | 1
47 | ```
48 |
49 | ## Remarks
50 | > Note that `cond` is syntactic sugar for a nested `if`.
51 |
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/cons-stream.md:
--------------------------------------------------------------------------------
1 | # cons-stream
2 | A derived expression for constructing a stream, i.e. a pair of an immediately evaluated expression and a delayed one.
3 | ```
4 | (cons-stream expression expression)
5 | ```
6 |
7 | The first expression is evaluated immediately and the second one is delayed. The result of the `cons-stream` expression
8 | is a pair made of the value of the first expression and a procedure which evaluates the second one when called, i.e. a promise.
9 |
10 | ## Examples
11 | ```scheme
12 | (cons-stream 1 2)
13 | ```
14 | -> *(1 . [UserProcedure] Parameters: 0)*
15 |
16 | ```scheme
17 | ; Assign the procedure to a variable and call it later.
18 | (define delayed (cdr (cons-stream 1 2)))
19 | (delayed)
20 | ```
21 | -> *2*
22 |
23 | ```scheme
24 | ; Use the force library procedure to force the evaluation.
25 | (force (cdr (cons-stream 1 2)))
26 | ```
27 | -> *2*
28 |
29 | ```scheme
30 | ; Use the cdr-stream library procedure to force the evaluation.
31 | (cdr-stream (cons-stream 1 2))
32 | ```
33 | -> *2*
34 |
35 | ## Remarks
36 | > Note that `(cons-stream a b)` is syntactic sugar for `(cons a (delay b))`.
37 |
38 | > Note that the procedure created for the delayed expression is a memoized one. I.e. the expression is evaluated once
39 | when needed and subsequent calls will simply return the previously calculated value.
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/delay.md:
--------------------------------------------------------------------------------
1 | # delay
2 | A special form that delays the evaluation of the given expression, effectively creating a promise to evaluate it in the future.
3 | The evaluation result is a procedure which evaluates the expression when called.
4 | ```
5 | (delay expression)
6 | ```
7 |
8 | ## Examples
9 | ```scheme
10 | ; Delay displaying "Hello World!".
11 | (delay (display "Hello World!"))
12 | ```
13 | -> *[UserProcedure] Parameters: 0*
14 |
15 | ```scheme
16 | ; Assign the procedure to a variable and call it later.
17 | (define delayed (delay (display "Hello World!")))
18 | (delayed)
19 | ```
20 | -> *Hello World!*
21 |
22 | ```scheme
23 | ; Use the force library procedure to force the evaluation.
24 | (force (delay (display "Hello World!")))
25 | ```
26 | -> *Hello World!*
27 |
28 | ## Remarks
29 |
30 | > `(delay a)` is equivalent to `(lambda() a)`. So, it needs to be a special form; otherwise `(delay a)`
31 | would cause `a` to be evaluated before calling `delay` on it, due to the language's applicative order of evaluation
32 | which dictates that arguments are evaluated first before applying a procedure on them.
33 |
34 | > Note that the procedure created for the delayed expression is a memoized one. I.e. the expression is evaluated once
35 | when needed and subsequent calls will simply return the previously calculated value.
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/function-application.md:
--------------------------------------------------------------------------------
1 | # Procedure Application
2 | A special form for applying a procedure to optional arguments. This is typically known as a procedure call.
3 |
4 | The first expression gives the procedure to call. The following zero or more expressions
5 | are evaluated from left to right and give the arguments passed to the procedure's parameters.
6 |
7 | ```
8 | (expression . expressions)
9 | ```
10 | The body of the procedure is evaluated in a new inner scope where the procedure's parameters are
11 | bound to the values passed as arguments.
12 |
13 | ## Examples
14 | ```scheme
15 | ; Call the primitive procedure +.
16 | (+ 1 2 3 4)
17 | ```
18 | -> *10*
19 |
20 | ```scheme
21 | ; Define a procedure that prints 1 and 2 to the standard output on different lines.
22 | (define (print-to-2)
23 | (define x 1)
24 | (display x)
25 | (newline)
26 | (set! x (+ x 1))
27 | (display x)
28 | (newline))
29 |
30 | ; Call the procedure.
31 | (print-to-2)
32 | ```
33 | ->
34 | ```
35 | 1
36 | 2
37 | ```
38 |
39 | ```scheme
40 | ; Define a procedure giving the absolute value of a number.
41 | (define (abs x)
42 | (if (< x 0)
43 | (* -1 x)
44 | x))
45 |
46 | ; Call the procedure.
47 | (abs -7)
48 | ```
49 | -> *7*
50 |
51 | ```scheme
52 | ; Create an anonymous user procedure, i.e. a lambda, that returns
53 | ; the greater of two numbers and apply it to arguments 4 and 9.
54 | ((lambda (x y)
55 | (if (>= x y)
56 | x
57 | y)) 4 9)
58 | ```
59 | -> *9*
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/if.md:
--------------------------------------------------------------------------------
1 | # if
2 | A special form for declaring alternative expressions to be evaluated based on the result of a predicate.
3 |
4 | ```
5 | (if predicate consequent alternative)
6 | ```
7 |
8 | The first expression is the predicate. The second is the consequent, which is evaluated if the predicate evaluates to true.
9 | The optional last one is the alternative, which is evaluated if the predicate evaluates to false.
10 | If the alternative is to be evaluated and there is none, the result is unspecified.
11 |
12 | ## Examples
13 | ```scheme
14 | (if true 1 0)
15 | ```
16 | -> *1*
17 |
18 | ```scheme
19 | (if false 1 0)
20 | ```
21 | -> *0*
22 |
23 | ```scheme
24 | (if (> 1 0) "1 is positive.")
25 | ```
26 | -> *"1 is positive."*
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/lambda.md:
--------------------------------------------------------------------------------
1 | # lambda
2 | A special form for creating a user procedure with zero or more parameters. The body is executed when the procedure is called.
3 | ```
4 | (lambda (. parameters) body)
5 | ```
6 |
7 | The procedure's body consists of zero or more definitions, followed by at least one expression.
8 | The expressions are evaluated in the order they appear and the evaluation result of the last one
9 | is the final result of the procedure when called.
10 |
11 | ## Examples
12 | ```scheme
13 | ; Create a user procedure that returns the greater of two numbers.
14 | (lambda (x y)
15 | (if (>= x y)
16 | x
17 | y))
18 | ```
19 | -> *[UserProcedure] Parameters: x, y*
20 |
21 | ```scheme
22 | ; Create an anonymous user procedure, i.e. a lambda, that returns
23 | ; the greater of two numbers and apply it to arguments 4 and 9.
24 | ((lambda (x y)
25 | (if (>= x y)
26 | x
27 | y)) 4 9)
28 | ```
29 | -> *9*
30 |
31 | ```scheme
32 | ; Create a procedure that prints the sum of a number's multiple of 10
33 | ; with its multiple of 100 to the standard output.
34 | (lambda (x)
35 | (define y1 (* x 10))
36 | (define y2 (* x 100))
37 | (display (+ y1 y2)))
38 | ```
39 | -> *[UserProcedure] Parameters: x*
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/let.md:
--------------------------------------------------------------------------------
1 | # let
2 | A derived expression for declaring variables and expressions using them, in a scope limited
3 | within the `let` expression itself. It has one or more let clauses, the `(id expression)` part, which define the variables,
4 | followed by a body.
5 | ```
6 | (let ((id expression)) body)
7 | ```
8 |
9 | A let clause starts with an `id` being the name of the variable, followed by an expression that gives its value.
10 |
11 | The body consists of zero or more definitions, followed by at least one expression.
12 | The expressions are evaluated in the order they appear and the evaluation result of the last one
13 | is the final result of the `let` expression.
14 |
15 | ## Examples
16 | ```scheme
17 | ; Declare a and b in a local scope and add them.
18 | (let ((a 1) (b 2))
19 | (+ a b))
20 | ```
21 | -> *3*
22 |
23 | ```scheme
24 | ; Define a procedure that calculates some formula based on parameter x.
25 | (define (foo x)
26 | (let ((a (+ x 1))
27 | (b (+ x 2)))
28 | (define c (* a b))
29 | (+ x a b c)))
30 |
31 | (foo 4) ; Call the procedure.
32 | ```
33 | -> *45*
34 |
35 | ## Remarks
36 |
37 | > Note that `let` is syntactic sugar for [lambda application](function-application.md).
38 |
39 | I.e.
40 |
41 | ```scheme
42 | (let ((a 1) (b 2))
43 | (+ a b))
44 | ```
45 |
46 | is really a user procedure with two parameters `a` and `b`, being called with arguments `1` and `2`.
47 |
48 | ```scheme
49 | ((lambda (a b)
50 | (+ a b)) 1 2)
51 | ```
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/or.md:
--------------------------------------------------------------------------------
1 | # or
2 | A derived expression that implements a logical or. It accepts at least one expression.
3 | ```
4 | (or expression . expressions)
5 | ```
6 | Each expression is evaluated from left to right, until one evaluates to true or the last expression is reached, in which case it is the result of the evaluation.
7 |
8 | ## Examples
9 | ```scheme
10 | (or false true false)
11 | ```
12 | -> *true*
13 |
14 | ```scheme
15 | (or false false false)
16 | ```
17 | -> *false*
18 |
19 | ```scheme
20 | (or (< 1 0) (> 2 1) (< 3 2))
21 | ```
22 | -> *true*
23 |
24 | ```scheme
25 | (or (< 1 0) (< 2 1) (< 3 2))
26 | ```
27 | -> *false*
28 |
29 | ## Remarks
30 | > `or` is syntactic sugar for a nested `if`.
31 |
32 | > Note that in traditional LISP `(or)` with no operands, evaluates to `false`. RainLisp differentiates in this regard.
--------------------------------------------------------------------------------
/RainLisp/Docs/special-forms-derived-expressions/set!.md:
--------------------------------------------------------------------------------
1 | # set!
2 | Assignment is a special form for changing a variable's value.
3 | `id` is the identifier of the variable to change and `expression` gives the new value.
4 | ```
5 | (set! id expression)
6 | ```
7 | The identifier needs to be visible in the current scope; otherwise, an error occurs.
8 | The evaluation result of the assignment itself is unspecified.
9 |
10 | ## Examples
11 | ```scheme
12 | (define my-var 1) ; Define a variable.
13 | (set! my-var 20) ; Change its value.
14 |
15 | my-var ; Get its value.
16 | ```
17 | -> *20*
18 |
19 | ```scheme
20 | ; Define a function with one parameter.
21 | (define (foo x)
22 | ; Increment the parameter's value.
23 | (set! x (+ x 1))
24 | ; Return its value.
25 | x)
26 |
27 | (foo 3) ; Call the function.
28 | ```
29 | -> *4*
30 |
31 | ```scheme
32 | ; Set a value to a variable that is not defined in the current scope.
33 | (set! a 5)
34 | ```
35 | -> Gives the following error.
36 | ```
37 | Unknown identifier a.
38 | Call Stack
39 | [Assignment a] Line 2, position 2.
40 | ```
--------------------------------------------------------------------------------
/RainLisp/ErrorMessages.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp
2 | {
3 | ///
4 | /// Messages for errors that may occur during code interpretation.
5 | ///
6 | internal static class ErrorMessages
7 | {
8 | internal const string CALL_STACK = "Call Stack";
9 | internal const string DEBUG_INFO = "[{0}] Line {1}, position {2}.";
10 |
11 | internal const string NON_TERMINATED_STRING = "The string is not terminated. Line {0}, position {1}.";
12 | internal const string INVALID_ESCAPE_SEQUENCE = "Invalid escape sequence \\{0}. Line {1}, position {2}.";
13 | internal const string INVALID_STRING_CHARACTER = "Invalid string character {0}. Line {1}, position {2}.";
14 | internal const string INVALID_NUMBER_CHARACTER = "Invalid number character {0}. Line {1}, position {2}.";
15 |
16 | internal const string PARSING_ERROR = "Syntax error. Line {0}, position {1}. Expecting {2}.";
17 | internal const string SYMBOL_SEPARATOR = " or ";
18 |
19 | internal const string WRONG_NUMBER_OF_ARGUMENTS = "Wrong number of arguments, expecting {0} but got {1}.";
20 | internal const string WRONG_NUMBER_OF_ARGUMENTS_EXT = "Wrong number of arguments, expecting {0} or more but got {1}.";
21 | internal const string WRONG_TYPE_OF_ARGUMENT = "Wrong type of argument, expecting {0}, but got {1}.";
22 | internal const string WRONG_TYPE_OF_ARGUMENT_FOR_MANY = "Wrong type of argument, expecting one of {0}, but got {1}.";
23 | internal const string UNKNOWN_IDENTIFIER = "Unknown identifier {0}.";
24 | internal const string NOT_PROCEDURE = "Not a procedure.";
25 | internal const string USER_ERROR = "User error: {0}";
26 | internal const string INVALID_VALUE = "Invalid value.";
27 |
28 | internal const string UNKNOWN_ERROR = "Unknown error.";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/IEnvironmentFactory.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation
2 | {
3 | ///
4 | /// Represents a factory for creating instances of .
5 | ///
6 | public interface IEnvironmentFactory
7 | {
8 | ///
9 | /// Returns an evaluation environment.
10 | ///
11 | /// The new evaluation environment.
12 | IEvaluationEnvironment CreateEnvironment();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/IProcedureApplicationVisitor.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation.Results;
2 |
3 | namespace RainLisp.Evaluation
4 | {
5 | ///
6 | /// Represents a visitor that is capable of applying, i.e. calling, user and primitive procedures.
7 | ///
8 | public interface IProcedureApplicationVisitor
9 | {
10 | ///
11 | /// Returns the result of applying a user procedure.
12 | ///
13 | /// The user procedure to be called. It is the result of an evaluation.
14 | /// The evaluated arguments to be passed to the procedure's parameters.
15 | /// An evaluator that is capable of evaluating the body of the procedure.
16 | /// The result of calling the user procedure.
17 | /// The is called with the wrong number of arguments.
18 | /// An error occurs during the evaluation of the 's body.
19 | EvaluationResult ApplyUserProcedure(UserProcedure procedure, EvaluationResult[]? evaluatedArguments, IEvaluatorVisitor evaluatorVisitor);
20 |
21 | ///
22 | /// Returns the result of applying a primitive procedure.
23 | ///
24 | /// The primitive procedure to be called. It is the result of an evaluation.
25 | /// The evaluated arguments to be passed to the procedure's parameters.
26 | /// The result of calling the primitive procedure.
27 | EvaluationResult ApplyPrimitiveProcedure(PrimitiveProcedure procedure, EvaluationResult[]? evaluatedArguments);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/Results/BoolDatum.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation.Results
2 | {
3 | ///
4 | /// Represents a boolean primitive datum as a result of an evaluation.
5 | ///
6 | public class BoolDatum : PrimitiveDatum
7 | {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The underlying primitive value.
12 | public BoolDatum(bool value) : base(value)
13 | {
14 | }
15 |
16 | ///
17 | /// Accepts a visitor that performs some operation on the boolean primitive and returns a .
18 | ///
19 | /// The result of the visitor's operation on the boolean primitive.
20 | /// The visitor that performs an operation.
21 | /// A as a result of the visitor's operation.
22 | public override T AcceptVisitor(IEvaluationResultVisitor visitor)
23 | => visitor.VisitBoolDatum(this);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/Results/DateTimeDatum.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation.Results
2 | {
3 | ///
4 | /// Represents a date and time primitive datum as a result of an evaluation.
5 | ///
6 | public class DateTimeDatum : PrimitiveDatum
7 | {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The underlying primitive value.
12 | public DateTimeDatum(DateTime value) : base(value)
13 | {
14 | }
15 |
16 | ///
17 | /// Accepts a visitor that performs some operation on the date and time primitive and returns a .
18 | ///
19 | /// The result of the visitor's operation on the date and time primitive.
20 | /// The visitor that performs an operation.
21 | /// A as a result of the visitor's operation.
22 | public override T AcceptVisitor(IEvaluationResultVisitor visitor)
23 | => visitor.VisitDateTimeDatum(this);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/Results/IPrimitiveDatum.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation.Results
2 | {
3 | ///
4 | /// Represents a primitive datum as a result of an evaluation.
5 | ///
6 | public interface IPrimitiveDatum
7 | {
8 | ///
9 | /// Returns the underlying primitive datum's value as an object.
10 | ///
11 | /// The underlying primitive datum's value as an object.
12 | object GetValueAsObject();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/Results/Nil.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation.Results
2 | {
3 | ///
4 | /// Represents a nil result of an evaluation, also known as the empty list.
5 | ///
6 | public class Nil : EvaluationResult
7 | {
8 | // A private constructor prohibits others from creating instances of this type.
9 | private Nil()
10 | {
11 | }
12 |
13 | private static Nil? nil;
14 |
15 | ///
16 | /// Returns the nil evaluation result which is the same instance in a system wide scope.
17 | ///
18 | /// The nil evaluation result.
19 | public static Nil GetNil()
20 | {
21 | nil ??= new Nil();
22 | return nil;
23 | }
24 |
25 | ///
26 | /// Accepts a visitor that performs some operation on the nil evaluation result and returns a .
27 | ///
28 | /// The result of the visitor's operation on the nil evaluation result.
29 | /// The visitor that performs an operation.
30 | /// A as a result of the visitor's operation.
31 | public override T AcceptVisitor(IEvaluationResultVisitor visitor)
32 | => visitor.VisitNil(this);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/Results/NumberDatum.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation.Results
2 | {
3 | ///
4 | /// Represents a numeric primitive datum as a result of an evaluation.
5 | ///
6 | public class NumberDatum : PrimitiveDatum
7 | {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The underlying primitive value.
12 | public NumberDatum(double value) : base(value)
13 | {
14 | }
15 |
16 | ///
17 | /// Accepts a visitor that performs some operation on the numeric primitive and returns a .
18 | ///
19 | /// The result of the visitor's operation on the numeric primitive.
20 | /// The visitor that performs an operation.
21 | /// A as a result of the visitor's operation.
22 | public override T AcceptVisitor(IEvaluationResultVisitor visitor)
23 | => visitor.VisitNumberDatum(this);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/Results/Pair.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation.Results
2 | {
3 | ///
4 | /// Represents the basic data structure as a result of an evaluation.
5 | /// It consists of two parts and based on it, other more complex data structures can be built.
6 | ///
7 | public class Pair : EvaluationResult
8 | {
9 | ///
10 | /// Initializes a new instance of the class.
11 | ///
12 | /// The first part of the pair.
13 | /// The second part of the pair.
14 | public Pair(EvaluationResult first, EvaluationResult second)
15 | {
16 | First = first;
17 | Second = second;
18 | }
19 |
20 | ///
21 | /// Gets or sets the first part of the pair.
22 | ///
23 | public EvaluationResult First { get; set; }
24 |
25 | ///
26 | /// Gets or sets the second part of the pair.
27 | ///
28 | public EvaluationResult Second { get; set; }
29 |
30 | ///
31 | /// Accepts a visitor that performs some operation on the pair and returns a .
32 | ///
33 | /// The result of the visitor's operation on the pair.
34 | /// The visitor that performs an operation.
35 | /// A as a result of the visitor's operation.
36 | public override T AcceptVisitor(IEvaluationResultVisitor visitor)
37 | => visitor.VisitPair(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/Results/QuoteSymbol.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation.Results
2 | {
3 | ///
4 | /// Represents a quote symbol as a result of an evaluation.
5 | ///
6 | public class QuoteSymbol : EvaluationResult
7 | {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The text of the quote symbol.
12 | public QuoteSymbol(string symbolText)
13 | => SymbolText = symbolText;
14 |
15 | ///
16 | /// Gets or sets the text of the quote symbol.
17 | ///
18 | public string SymbolText { get; init; }
19 |
20 | ///
21 | /// Accepts a visitor that performs some operation on the quote symbol and returns a .
22 | ///
23 | /// The result of the visitor's operation on the quote symbol.
24 | /// The visitor that performs an operation.
25 | /// A as a result of the visitor's operation.
26 | public override T AcceptVisitor(IEvaluationResultVisitor visitor)
27 | => visitor.VisitQuoteSymbol(this);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/Results/StringDatum.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation.Results
2 | {
3 | ///
4 | /// Represents a string primitive datum as a result of an evaluation.
5 | ///
6 | public class StringDatum : PrimitiveDatum
7 | {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The underlying primitive value.
12 | public StringDatum(string value) : base(value)
13 | {
14 | }
15 |
16 | ///
17 | /// Accepts a visitor that performs some operation on the string primitive and returns a .
18 | ///
19 | /// The result of the visitor's operation on the string primitive.
20 | /// The visitor that performs an operation.
21 | /// A as a result of the visitor's operation.
22 | public override T AcceptVisitor(IEvaluationResultVisitor visitor)
23 | => visitor.VisitStringDatum(this);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/RainLisp/Evaluation/Results/Unspecified.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Evaluation.Results
2 | {
3 | ///
4 | /// Represents an unspecified result of an evaluation.
5 | ///
6 | public class Unspecified : EvaluationResult
7 | {
8 | // A private constructor prohibits others from creating instances of this type.
9 | private Unspecified()
10 | {
11 | }
12 |
13 | private static Unspecified? unspecified;
14 |
15 | ///
16 | /// Returns the unspecified evaluation result which is the same instance in a system wide scope.
17 | ///
18 | /// The unspecified evaluation result.
19 | public static Unspecified GetUnspecified()
20 | {
21 | unspecified ??= new Unspecified();
22 | return unspecified;
23 | }
24 |
25 | ///
26 | /// Accepts a visitor that performs some operation on the unspecified evaluation result and returns a .
27 | ///
28 | /// The result of the visitor's operation on the unspecified evaluation result.
29 | /// The visitor that performs an operation.
30 | /// A as a result of the visitor's operation.
31 | public override T AcceptVisitor(IEvaluationResultVisitor visitor)
32 | => visitor.VisitUnspecified(this);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/RainLisp/Grammar/Delimiters.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Grammar
2 | {
3 | ///
4 | /// Delimeters as defined in the lexical grammar of the language.
5 | ///
6 | public static class Delimiters
7 | {
8 | ///
9 | /// Opening parenthesis.
10 | ///
11 | public const char LPAREN = '(';
12 |
13 | ///
14 | /// Closing parenthesis.
15 | ///
16 | public const char RPAREN = ')';
17 |
18 | ///
19 | /// Space.
20 | ///
21 | public const char SPACE = ' ';
22 |
23 | ///
24 | /// Carriage return.
25 | ///
26 | public const char CARRIAGE_RETURN = '\r';
27 |
28 | ///
29 | /// New line.
30 | ///
31 | public const char NEW_LINE = '\n';
32 |
33 | ///
34 | /// Tab.
35 | ///
36 | public const char TAB = '\t';
37 |
38 | ///
39 | /// Double quote.
40 | ///
41 | public const char DOUBLE_QUOTE = '"';
42 |
43 | ///
44 | /// Single quote.
45 | ///
46 | public const char SINGLE_QUOTE = '\'';
47 |
48 | ///
49 | /// Start of inline comment.
50 | ///
51 | public const char COMMENT = ';';
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/RainLisp/Grammar/NumberSpecialChars.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Grammar
2 | {
3 | ///
4 | /// Characters that can be part of number literals, as defined in the lexical grammar of the language.
5 | ///
6 | public static class NumberSpecialChars
7 | {
8 | ///
9 | /// Positive sign for numeric literals.
10 | ///
11 | public const char PLUS = '+';
12 |
13 | ///
14 | /// Negative sign for numeric literals.
15 | ///
16 | public const char MINUS = '-';
17 |
18 | ///
19 | /// Decimal separator for numeric literals.
20 | ///
21 | public const char DOT = '.';
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/RainLisp/Grammar/StringEscapableChars.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Grammar
2 | {
3 | ///
4 | /// Characters that can be combined with a starting backslash \ character to form a valid escape sequence in a string literal, as defined in the lexical grammar of the language.
5 | ///
6 | public static class StringEscapableChars
7 | {
8 | ///
9 | /// Denotes the new line character if escaped.
10 | ///
11 | public const char ESCAPABLE_NEW_LINE = 'n';
12 |
13 | ///
14 | /// Denotes the carriage return character if escaped.
15 | ///
16 | public const char ESCAPABLE_CARRIAGE_RETURN = 'r';
17 |
18 | ///
19 | /// Denotes the tab character if escaped.
20 | ///
21 | public const char ESCAPABLE_TAB = 't';
22 |
23 | ///
24 | /// Denotes the double quote character if escaped.
25 | ///
26 | public const char ESCAPABLE_DOUBLE_QUOTE = '"';
27 |
28 | ///
29 | /// Denotes the backslash character if escaped.
30 | ///
31 | public const char ESCAPE = '\\';
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/RainLisp/IDebugInfo.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp
2 | {
3 | ///
4 | /// Debugging information.
5 | ///
6 | public interface IDebugInfo
7 | {
8 | ///
9 | /// Gets or sets the line in the source code.
10 | ///
11 | public uint Line { get; set; }
12 |
13 | ///
14 | /// Gets or sets the starting character position in the .
15 | ///
16 | public uint Position { get; set; }
17 |
18 | ///
19 | /// Gets or sets if relevant debugging info has been set.
20 | ///
21 | public bool HasDebugInfo { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/RainLisp/InterpreterDelegates.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp
2 | {
3 | ///
4 | /// Encapsulates a method accepting the string representation of an evaluation result.
5 | ///
6 | /// The string representation of the evaluation result.
7 | public delegate void PrintResult(string result);
8 |
9 | ///
10 | /// Encapsulates a method accepting information relating to an error during evaluation.
11 | ///
12 | /// The error message.
13 | /// The actual exception.
14 | /// true if the exception was not anticipated; otherwise, false. Default value is false.
15 | public delegate void PrintError(string message, Exception exception, bool unknownError = false);
16 | }
17 |
--------------------------------------------------------------------------------
/RainLisp/Parsing/Extensions.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.AbstractSyntaxTree;
2 | using RainLisp.Tokenization;
3 |
4 | namespace RainLisp.Parsing
5 | {
6 | ///
7 | /// Extension methods for syntax analysis.
8 | ///
9 | public static class Extensions
10 | {
11 | ///
12 | /// Attaches debugging information to the abstract syntax tree from .
13 | ///
14 | /// The expression to copy debugging info to.
15 | /// The token to copy debugging info from.
16 | /// The with debugging info.
17 | public static Expression WithDebugInfo(this Expression expression, Token token)
18 | {
19 | expression.Line = token.Line;
20 | expression.Position = token.Position;
21 | expression.HasDebugInfo = true;
22 |
23 | return expression;
24 | }
25 |
26 | ///
27 | /// Requires that the current token is an identifier. If it is, it advances the
28 | /// current position and returns the identifier's name; otherwise, it throws an exception.
29 | ///
30 | /// The token consumer to request the identifier from.
31 | /// The identifier's name.
32 | /// The required token is the last one, so the token position cannot be advanced.
33 | /// The current token's type is not an identifier.
34 | public static string RequireIdentifierName(this TokenConsumer tokenConsumer)
35 | {
36 | var currentToken = tokenConsumer.CurrentToken();
37 | tokenConsumer.Require(TokenType.Identifier);
38 |
39 | return currentToken.Value;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/RainLisp/Parsing/IParser.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.AbstractSyntaxTree;
2 | using RainLisp.Tokenization;
3 |
4 | namespace RainLisp.Parsing
5 | {
6 | ///
7 | /// Represents a parser that is capable of performing syntax analysis on tokens, based on the language's syntax grammar.
8 | ///
9 | public interface IParser
10 | {
11 | ///
12 | /// Returns an abstract syntax tree by syntactically analyzing tokens that are produced by a tokenizer.
13 | ///
14 | /// The tokens to syntactically analyze.
15 | /// An abstract syntax tree to evaluate.
16 | /// is null.
17 | /// is empty.
18 | /// The token sequence is syntactically incorrect.
19 | Program Parse(IList tokens);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/RainLisp/RainLisp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 | True
8 | RainLisp a .NET LISP implementation
9 | 1.4.0
10 | RainLisp a .NET LISP implementation.
11 | 2023
12 | https://github.com/chr1st0scli/RainLisp
13 | RainLisp-Colored-128x128.png
14 | nuget.md
15 | https://github.com/chr1st0scli/RainLisp
16 | lisp;interpreter;repl;programming;language;.net;
17 | LICENSE.txt
18 | Christos Giamouridis
19 | Rainsoft
20 | True
21 | https://github.com/chr1st0scli/RainLisp/releases
22 |
23 |
24 |
25 |
26 | True
27 | \
28 |
29 |
30 | True
31 | \
32 |
33 |
34 | True
35 | \
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/RainLisp/Tokenization/ITokenizer.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Tokenization
2 | {
3 | ///
4 | /// Represents a tokenizer capable of performing lexical analysis on the code, based on the language's lexical grammar.
5 | ///
6 | public interface ITokenizer
7 | {
8 | ///
9 | /// Performs lexical analysis on code and produces tokens as a result.
10 | ///
11 | /// The code to lexically analyze.
12 | /// A list of tokens that always terminates with an token.
13 | /// A string literal is not properly terminated.
14 | /// An invalid string literal escape sequence is provided.
15 | /// An invalid string literal character is provided.
16 | /// An invalid character for a numeric literal is provided.
17 | IList Tokenize(string? code);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/RainLisp/Tokenization/Token.cs:
--------------------------------------------------------------------------------
1 | namespace RainLisp.Tokenization
2 | {
3 | ///
4 | /// Represents the product of lexical analysis.
5 | ///
6 | public class Token
7 | {
8 | ///
9 | /// Gets or sets the type of the token.
10 | ///
11 | public TokenType Type { get; init; }
12 |
13 | ///
14 | /// Gets or sets the sequence of characters that make up the token.
15 | ///
16 | public string Value { get; init; } = string.Empty;
17 |
18 | ///
19 | /// Gets or sets the numeric value of the token in case it is a number.
20 | ///
21 | public double NumberValue { get; init; }
22 |
23 | ///
24 | /// Gets or sets the boolean value of the token in case it is a boolean.
25 | ///
26 | public bool BooleanValue { get; init; }
27 |
28 | ///
29 | /// Gets or sets the string value of the token in case it is a string.
30 | ///
31 | public string StringValue { get; init; } = string.Empty;
32 |
33 | ///
34 | /// Gets or sets the line in the code which the token starts in.
35 | ///
36 | public uint Line { get; init; }
37 |
38 | ///
39 | /// Gets or sets the character position in the where the token starts at.
40 | ///
41 | public uint Position { get; init; }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/00.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Value": 1.0,
5 | "TypeName": "NumberLiteral"
6 | }
7 | ]
8 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/01.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Value": 1.5,
5 | "TypeName": "NumberLiteral"
6 | }
7 | ]
8 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/02.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Value": true,
5 | "TypeName": "BooleanLiteral"
6 | }
7 | ]
8 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/03.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Value": false,
5 | "TypeName": "BooleanLiteral"
6 | }
7 | ]
8 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/04.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Name": "foo",
5 | "TypeName": "Identifier"
6 | }
7 | ]
8 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/05.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Quotable": {
5 | "Text": "a",
6 | "Quotables": null
7 | },
8 | "TypeName": "Quote"
9 | }
10 | ]
11 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/06.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "a",
5 | "Value": {
6 | "Value": 1.0,
7 | "TypeName": "NumberLiteral"
8 | },
9 | "TypeName": "Assignment"
10 | }
11 | ]
12 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/07.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "a",
5 | "Value": {
6 | "Value": 1.0,
7 | "TypeName": "NumberLiteral"
8 | },
9 | "TypeName": "Definition"
10 | }
11 | ]
12 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/08.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "a",
5 | "Value": {
6 | "Parameters": null,
7 | "Body": {
8 | "Definitions": null,
9 | "Expressions": [
10 | {
11 | "Value": 1.0,
12 | "TypeName": "NumberLiteral"
13 | }
14 | ],
15 | "TypeName": "Body"
16 | },
17 | "TypeName": "Lambda"
18 | },
19 | "TypeName": "Definition"
20 | }
21 | ]
22 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/09.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "a",
5 | "Value": {
6 | "Parameters": [
7 | "b"
8 | ],
9 | "Body": {
10 | "Definitions": null,
11 | "Expressions": [
12 | {
13 | "Value": 1.0,
14 | "TypeName": "NumberLiteral"
15 | }
16 | ],
17 | "TypeName": "Body"
18 | },
19 | "TypeName": "Lambda"
20 | },
21 | "TypeName": "Definition"
22 | }
23 | ]
24 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/10.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "a",
5 | "Value": {
6 | "Parameters": [
7 | "b",
8 | "c"
9 | ],
10 | "Body": {
11 | "Definitions": null,
12 | "Expressions": [
13 | {
14 | "Operator": {
15 | "Name": "+",
16 | "TypeName": "Identifier"
17 | },
18 | "Operands": [
19 | {
20 | "Name": "b",
21 | "TypeName": "Identifier"
22 | },
23 | {
24 | "Name": "c",
25 | "TypeName": "Identifier"
26 | }
27 | ],
28 | "TypeName": "Application"
29 | }
30 | ],
31 | "TypeName": "Body"
32 | },
33 | "TypeName": "Lambda"
34 | },
35 | "TypeName": "Definition"
36 | }
37 | ]
38 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/11.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "foo",
5 | "Value": {
6 | "Parameters": [
7 | "x"
8 | ],
9 | "Body": {
10 | "Definitions": [
11 | {
12 | "IdentifierName": "innerfoo",
13 | "Value": {
14 | "Parameters": [
15 | "y"
16 | ],
17 | "Body": {
18 | "Definitions": null,
19 | "Expressions": [
20 | {
21 | "Operator": {
22 | "Name": "+",
23 | "TypeName": "Identifier"
24 | },
25 | "Operands": [
26 | {
27 | "Name": "x",
28 | "TypeName": "Identifier"
29 | },
30 | {
31 | "Name": "y",
32 | "TypeName": "Identifier"
33 | }
34 | ],
35 | "TypeName": "Application"
36 | }
37 | ],
38 | "TypeName": "Body"
39 | },
40 | "TypeName": "Lambda"
41 | },
42 | "TypeName": "Definition"
43 | }
44 | ],
45 | "Expressions": [
46 | {
47 | "Operator": {
48 | "Name": "innerfoo",
49 | "TypeName": "Identifier"
50 | },
51 | "Operands": [
52 | {
53 | "Value": 1.0,
54 | "TypeName": "NumberLiteral"
55 | }
56 | ],
57 | "TypeName": "Application"
58 | }
59 | ],
60 | "TypeName": "Body"
61 | },
62 | "TypeName": "Lambda"
63 | },
64 | "TypeName": "Definition"
65 | }
66 | ]
67 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/12.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Predicate": {
5 | "Value": true,
6 | "TypeName": "BooleanLiteral"
7 | },
8 | "Consequent": {
9 | "Value": 1.0,
10 | "TypeName": "NumberLiteral"
11 | },
12 | "Alternative": null,
13 | "TypeName": "If"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/13.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Predicate": {
5 | "Value": true,
6 | "TypeName": "BooleanLiteral"
7 | },
8 | "Consequent": {
9 | "Value": 1.0,
10 | "TypeName": "NumberLiteral"
11 | },
12 | "Alternative": {
13 | "Value": 0.0,
14 | "TypeName": "NumberLiteral"
15 | },
16 | "TypeName": "If"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/14.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Expressions": [
5 | {
6 | "Value": 1.0,
7 | "TypeName": "NumberLiteral"
8 | }
9 | ],
10 | "TypeName": "Begin"
11 | }
12 | ]
13 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/15.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Expressions": [
5 | {
6 | "Value": 1.0,
7 | "TypeName": "NumberLiteral"
8 | },
9 | {
10 | "Value": 2.0,
11 | "TypeName": "NumberLiteral"
12 | },
13 | {
14 | "Value": 3.0,
15 | "TypeName": "NumberLiteral"
16 | }
17 | ],
18 | "TypeName": "Begin"
19 | }
20 | ]
21 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/16.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Parameters": null,
5 | "Body": {
6 | "Definitions": null,
7 | "Expressions": [
8 | {
9 | "Value": 1.0,
10 | "TypeName": "NumberLiteral"
11 | }
12 | ],
13 | "TypeName": "Body"
14 | },
15 | "TypeName": "Lambda"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/17.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Parameters": [
5 | "x"
6 | ],
7 | "Body": {
8 | "Definitions": null,
9 | "Expressions": [
10 | {
11 | "Name": "x",
12 | "TypeName": "Identifier"
13 | }
14 | ],
15 | "TypeName": "Body"
16 | },
17 | "TypeName": "Lambda"
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/18.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Parameters": [
5 | "x",
6 | "y"
7 | ],
8 | "Body": {
9 | "Definitions": null,
10 | "Expressions": [
11 | {
12 | "Value": 1.0,
13 | "TypeName": "NumberLiteral"
14 | }
15 | ],
16 | "TypeName": "Body"
17 | },
18 | "TypeName": "Lambda"
19 | }
20 | ]
21 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/19.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Parameters": [
5 | "x",
6 | "y"
7 | ],
8 | "Body": {
9 | "Definitions": null,
10 | "Expressions": [
11 | {
12 | "Operator": {
13 | "Name": "+",
14 | "TypeName": "Identifier"
15 | },
16 | "Operands": [
17 | {
18 | "Name": "x",
19 | "TypeName": "Identifier"
20 | },
21 | {
22 | "Name": "y",
23 | "TypeName": "Identifier"
24 | }
25 | ],
26 | "TypeName": "Application"
27 | }
28 | ],
29 | "TypeName": "Body"
30 | },
31 | "TypeName": "Lambda"
32 | }
33 | ]
34 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/20.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Name": "foo",
6 | "TypeName": "Identifier"
7 | },
8 | "Operands": null,
9 | "TypeName": "Application"
10 | }
11 | ]
12 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/21.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Name": "foo",
6 | "TypeName": "Identifier"
7 | },
8 | "Operands": [
9 | {
10 | "Value": 1.0,
11 | "TypeName": "NumberLiteral"
12 | }
13 | ],
14 | "TypeName": "Application"
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/22.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Name": "foo",
6 | "TypeName": "Identifier"
7 | },
8 | "Operands": [
9 | {
10 | "Value": 1.0,
11 | "TypeName": "NumberLiteral"
12 | },
13 | {
14 | "Value": 2.0,
15 | "TypeName": "NumberLiteral"
16 | },
17 | {
18 | "Value": 3.0,
19 | "TypeName": "NumberLiteral"
20 | }
21 | ],
22 | "TypeName": "Application"
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/23.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": null,
6 | "Body": {
7 | "Definitions": null,
8 | "Expressions": [
9 | {
10 | "Value": 1.0,
11 | "TypeName": "NumberLiteral"
12 | }
13 | ],
14 | "TypeName": "Body"
15 | },
16 | "TypeName": "Lambda"
17 | },
18 | "Operands": null,
19 | "TypeName": "Application"
20 | }
21 | ]
22 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/24.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": [
6 | "x"
7 | ],
8 | "Body": {
9 | "Definitions": null,
10 | "Expressions": [
11 | {
12 | "Name": "x",
13 | "TypeName": "Identifier"
14 | }
15 | ],
16 | "TypeName": "Body"
17 | },
18 | "TypeName": "Lambda"
19 | },
20 | "Operands": [
21 | {
22 | "Value": 1.0,
23 | "TypeName": "NumberLiteral"
24 | }
25 | ],
26 | "TypeName": "Application"
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/25.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Predicate": {
5 | "Value": true,
6 | "TypeName": "BooleanLiteral"
7 | },
8 | "Consequent": {
9 | "Value": 5.0,
10 | "TypeName": "NumberLiteral"
11 | },
12 | "Alternative": null,
13 | "TypeName": "If"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/26.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Predicate": {
5 | "Value": true,
6 | "TypeName": "BooleanLiteral"
7 | },
8 | "Consequent": {
9 | "Value": 5.0,
10 | "TypeName": "NumberLiteral"
11 | },
12 | "Alternative": {
13 | "Predicate": {
14 | "Value": false,
15 | "TypeName": "BooleanLiteral"
16 | },
17 | "Consequent": {
18 | "Value": 10.0,
19 | "TypeName": "NumberLiteral"
20 | },
21 | "Alternative": null,
22 | "TypeName": "If"
23 | },
24 | "TypeName": "If"
25 | }
26 | ]
27 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/27.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Predicate": {
5 | "Value": true,
6 | "TypeName": "BooleanLiteral"
7 | },
8 | "Consequent": {
9 | "Value": 5.0,
10 | "TypeName": "NumberLiteral"
11 | },
12 | "Alternative": {
13 | "Predicate": {
14 | "Value": false,
15 | "TypeName": "BooleanLiteral"
16 | },
17 | "Consequent": {
18 | "Value": 10.0,
19 | "TypeName": "NumberLiteral"
20 | },
21 | "Alternative": {
22 | "Value": -1.0,
23 | "TypeName": "NumberLiteral"
24 | },
25 | "TypeName": "If"
26 | },
27 | "TypeName": "If"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/28.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Predicate": {
5 | "Operator": {
6 | "Name": "<=",
7 | "TypeName": "Identifier"
8 | },
9 | "Operands": [
10 | {
11 | "Name": "a",
12 | "TypeName": "Identifier"
13 | },
14 | {
15 | "Value": 5.0,
16 | "TypeName": "NumberLiteral"
17 | }
18 | ],
19 | "TypeName": "Application"
20 | },
21 | "Consequent": {
22 | "Value": 5.0,
23 | "TypeName": "NumberLiteral"
24 | },
25 | "Alternative": {
26 | "Predicate": {
27 | "Operator": {
28 | "Name": "<=",
29 | "TypeName": "Identifier"
30 | },
31 | "Operands": [
32 | {
33 | "Name": "a",
34 | "TypeName": "Identifier"
35 | },
36 | {
37 | "Value": 10.0,
38 | "TypeName": "NumberLiteral"
39 | }
40 | ],
41 | "TypeName": "Application"
42 | },
43 | "Consequent": {
44 | "Value": 10.0,
45 | "TypeName": "NumberLiteral"
46 | },
47 | "Alternative": {
48 | "Value": -1.0,
49 | "TypeName": "NumberLiteral"
50 | },
51 | "TypeName": "If"
52 | },
53 | "TypeName": "If"
54 | }
55 | ]
56 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/29.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Predicate": {
5 | "Value": true,
6 | "TypeName": "BooleanLiteral"
7 | },
8 | "Consequent": {
9 | "Expressions": [
10 | {
11 | "Value": 1.0,
12 | "TypeName": "NumberLiteral"
13 | },
14 | {
15 | "Value": 2.0,
16 | "TypeName": "NumberLiteral"
17 | }
18 | ],
19 | "TypeName": "Begin"
20 | },
21 | "Alternative": {
22 | "Predicate": {
23 | "Value": false,
24 | "TypeName": "BooleanLiteral"
25 | },
26 | "Consequent": {
27 | "Expressions": [
28 | {
29 | "Value": 3.0,
30 | "TypeName": "NumberLiteral"
31 | },
32 | {
33 | "Value": 4.0,
34 | "TypeName": "NumberLiteral"
35 | }
36 | ],
37 | "TypeName": "Begin"
38 | },
39 | "Alternative": {
40 | "Expressions": [
41 | {
42 | "Value": 5.0,
43 | "TypeName": "NumberLiteral"
44 | },
45 | {
46 | "Value": 6.0,
47 | "TypeName": "NumberLiteral"
48 | }
49 | ],
50 | "TypeName": "Begin"
51 | },
52 | "TypeName": "If"
53 | },
54 | "TypeName": "If"
55 | }
56 | ]
57 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/30.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": [
6 | "a"
7 | ],
8 | "Body": {
9 | "Definitions": null,
10 | "Expressions": [
11 | {
12 | "Name": "a",
13 | "TypeName": "Identifier"
14 | }
15 | ],
16 | "TypeName": "Body"
17 | },
18 | "TypeName": "Lambda"
19 | },
20 | "Operands": [
21 | {
22 | "Value": 1.0,
23 | "TypeName": "NumberLiteral"
24 | }
25 | ],
26 | "TypeName": "Application"
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/31.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": [
6 | "a",
7 | "b"
8 | ],
9 | "Body": {
10 | "Definitions": null,
11 | "Expressions": [
12 | {
13 | "Operator": {
14 | "Name": "+",
15 | "TypeName": "Identifier"
16 | },
17 | "Operands": [
18 | {
19 | "Name": "a",
20 | "TypeName": "Identifier"
21 | },
22 | {
23 | "Name": "b",
24 | "TypeName": "Identifier"
25 | }
26 | ],
27 | "TypeName": "Application"
28 | }
29 | ],
30 | "TypeName": "Body"
31 | },
32 | "TypeName": "Lambda"
33 | },
34 | "Operands": [
35 | {
36 | "Value": 1.0,
37 | "TypeName": "NumberLiteral"
38 | },
39 | {
40 | "Value": 2.0,
41 | "TypeName": "NumberLiteral"
42 | }
43 | ],
44 | "TypeName": "Application"
45 | }
46 | ]
47 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/32.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": [
6 | "a",
7 | "b"
8 | ],
9 | "Body": {
10 | "Definitions": [
11 | {
12 | "IdentifierName": "c",
13 | "Value": {
14 | "Value": 4.0,
15 | "TypeName": "NumberLiteral"
16 | },
17 | "TypeName": "Definition"
18 | }
19 | ],
20 | "Expressions": [
21 | {
22 | "Operator": {
23 | "Name": "+",
24 | "TypeName": "Identifier"
25 | },
26 | "Operands": [
27 | {
28 | "Name": "a",
29 | "TypeName": "Identifier"
30 | },
31 | {
32 | "Name": "b",
33 | "TypeName": "Identifier"
34 | },
35 | {
36 | "Name": "c",
37 | "TypeName": "Identifier"
38 | }
39 | ],
40 | "TypeName": "Application"
41 | }
42 | ],
43 | "TypeName": "Body"
44 | },
45 | "TypeName": "Lambda"
46 | },
47 | "Operands": [
48 | {
49 | "Value": 1.0,
50 | "TypeName": "NumberLiteral"
51 | },
52 | {
53 | "Value": 2.0,
54 | "TypeName": "NumberLiteral"
55 | }
56 | ],
57 | "TypeName": "Application"
58 | }
59 | ]
60 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/33.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": [
6 | "a",
7 | "b"
8 | ],
9 | "Body": {
10 | "Definitions": [
11 | {
12 | "IdentifierName": "c",
13 | "Value": {
14 | "Value": 4.0,
15 | "TypeName": "NumberLiteral"
16 | },
17 | "TypeName": "Definition"
18 | },
19 | {
20 | "IdentifierName": "d",
21 | "Value": {
22 | "Value": 5.0,
23 | "TypeName": "NumberLiteral"
24 | },
25 | "TypeName": "Definition"
26 | }
27 | ],
28 | "Expressions": [
29 | {
30 | "Operator": {
31 | "Name": "+",
32 | "TypeName": "Identifier"
33 | },
34 | "Operands": [
35 | {
36 | "Name": "a",
37 | "TypeName": "Identifier"
38 | },
39 | {
40 | "Name": "b",
41 | "TypeName": "Identifier"
42 | },
43 | {
44 | "Name": "c",
45 | "TypeName": "Identifier"
46 | },
47 | {
48 | "Name": "d",
49 | "TypeName": "Identifier"
50 | }
51 | ],
52 | "TypeName": "Application"
53 | }
54 | ],
55 | "TypeName": "Body"
56 | },
57 | "TypeName": "Lambda"
58 | },
59 | "Operands": [
60 | {
61 | "Value": 1.0,
62 | "TypeName": "NumberLiteral"
63 | },
64 | {
65 | "Value": 2.0,
66 | "TypeName": "NumberLiteral"
67 | }
68 | ],
69 | "TypeName": "Application"
70 | }
71 | ]
72 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/34.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "a",
5 | "Value": {
6 | "Parameters": null,
7 | "Body": {
8 | "Definitions": null,
9 | "Expressions": [
10 | {
11 | "Value": 1.0,
12 | "TypeName": "NumberLiteral"
13 | },
14 | {
15 | "Value": 2.0,
16 | "TypeName": "NumberLiteral"
17 | }
18 | ],
19 | "TypeName": "Body"
20 | },
21 | "TypeName": "Lambda"
22 | },
23 | "TypeName": "Definition"
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/35.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "a",
5 | "Value": {
6 | "Parameters": [
7 | "b"
8 | ],
9 | "Body": {
10 | "Definitions": null,
11 | "Expressions": [
12 | {
13 | "Value": 1.0,
14 | "TypeName": "NumberLiteral"
15 | },
16 | {
17 | "Value": 2.0,
18 | "TypeName": "NumberLiteral"
19 | },
20 | {
21 | "Value": 3.0,
22 | "TypeName": "NumberLiteral"
23 | }
24 | ],
25 | "TypeName": "Body"
26 | },
27 | "TypeName": "Lambda"
28 | },
29 | "TypeName": "Definition"
30 | }
31 | ]
32 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/36.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "a",
5 | "Value": {
6 | "Parameters": [
7 | "b",
8 | "c"
9 | ],
10 | "Body": {
11 | "Definitions": null,
12 | "Expressions": [
13 | {
14 | "Value": 1.0,
15 | "TypeName": "NumberLiteral"
16 | },
17 | {
18 | "Value": 2.0,
19 | "TypeName": "NumberLiteral"
20 | },
21 | {
22 | "Operator": {
23 | "Name": "+",
24 | "TypeName": "Identifier"
25 | },
26 | "Operands": [
27 | {
28 | "Name": "b",
29 | "TypeName": "Identifier"
30 | },
31 | {
32 | "Name": "c",
33 | "TypeName": "Identifier"
34 | }
35 | ],
36 | "TypeName": "Application"
37 | }
38 | ],
39 | "TypeName": "Body"
40 | },
41 | "TypeName": "Lambda"
42 | },
43 | "TypeName": "Definition"
44 | }
45 | ]
46 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/38.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Parameters": null,
5 | "Body": {
6 | "Definitions": null,
7 | "Expressions": [
8 | {
9 | "Value": 1.0,
10 | "TypeName": "NumberLiteral"
11 | },
12 | {
13 | "Value": 2.0,
14 | "TypeName": "NumberLiteral"
15 | }
16 | ],
17 | "TypeName": "Body"
18 | },
19 | "TypeName": "Lambda"
20 | }
21 | ]
22 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/39.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Parameters": [
5 | "x"
6 | ],
7 | "Body": {
8 | "Definitions": null,
9 | "Expressions": [
10 | {
11 | "Value": 1.0,
12 | "TypeName": "NumberLiteral"
13 | },
14 | {
15 | "Name": "x",
16 | "TypeName": "Identifier"
17 | }
18 | ],
19 | "TypeName": "Body"
20 | },
21 | "TypeName": "Lambda"
22 | }
23 | ]
24 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/40.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Parameters": [
5 | "x",
6 | "y"
7 | ],
8 | "Body": {
9 | "Definitions": null,
10 | "Expressions": [
11 | {
12 | "Value": 1.0,
13 | "TypeName": "NumberLiteral"
14 | },
15 | {
16 | "Value": 2.0,
17 | "TypeName": "NumberLiteral"
18 | }
19 | ],
20 | "TypeName": "Body"
21 | },
22 | "TypeName": "Lambda"
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/41.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Parameters": [
5 | "x",
6 | "y"
7 | ],
8 | "Body": {
9 | "Definitions": null,
10 | "Expressions": [
11 | {
12 | "Name": "x",
13 | "TypeName": "Identifier"
14 | },
15 | {
16 | "Name": "y",
17 | "TypeName": "Identifier"
18 | },
19 | {
20 | "Operator": {
21 | "Name": "+",
22 | "TypeName": "Identifier"
23 | },
24 | "Operands": [
25 | {
26 | "Name": "x",
27 | "TypeName": "Identifier"
28 | },
29 | {
30 | "Name": "y",
31 | "TypeName": "Identifier"
32 | }
33 | ],
34 | "TypeName": "Application"
35 | }
36 | ],
37 | "TypeName": "Body"
38 | },
39 | "TypeName": "Lambda"
40 | }
41 | ]
42 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/42.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": null,
6 | "Body": {
7 | "Definitions": null,
8 | "Expressions": [
9 | {
10 | "Value": 1.0,
11 | "TypeName": "NumberLiteral"
12 | },
13 | {
14 | "Value": 2.0,
15 | "TypeName": "NumberLiteral"
16 | }
17 | ],
18 | "TypeName": "Body"
19 | },
20 | "TypeName": "Lambda"
21 | },
22 | "Operands": null,
23 | "TypeName": "Application"
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/43.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": [
6 | "x"
7 | ],
8 | "Body": {
9 | "Definitions": null,
10 | "Expressions": [
11 | {
12 | "Value": 2.0,
13 | "TypeName": "NumberLiteral"
14 | },
15 | {
16 | "Name": "x",
17 | "TypeName": "Identifier"
18 | }
19 | ],
20 | "TypeName": "Body"
21 | },
22 | "TypeName": "Lambda"
23 | },
24 | "Operands": [
25 | {
26 | "Value": 1.0,
27 | "TypeName": "NumberLiteral"
28 | }
29 | ],
30 | "TypeName": "Application"
31 | }
32 | ]
33 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/44.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": [
6 | "a"
7 | ],
8 | "Body": {
9 | "Definitions": null,
10 | "Expressions": [
11 | {
12 | "Value": 1.0,
13 | "TypeName": "NumberLiteral"
14 | },
15 | {
16 | "Name": "a",
17 | "TypeName": "Identifier"
18 | }
19 | ],
20 | "TypeName": "Body"
21 | },
22 | "TypeName": "Lambda"
23 | },
24 | "Operands": [
25 | {
26 | "Value": 1.0,
27 | "TypeName": "NumberLiteral"
28 | }
29 | ],
30 | "TypeName": "Application"
31 | }
32 | ]
33 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/45.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": [
6 | "a",
7 | "b"
8 | ],
9 | "Body": {
10 | "Definitions": null,
11 | "Expressions": [
12 | {
13 | "Value": 1.0,
14 | "TypeName": "NumberLiteral"
15 | },
16 | {
17 | "Operator": {
18 | "Name": "+",
19 | "TypeName": "Identifier"
20 | },
21 | "Operands": [
22 | {
23 | "Name": "a",
24 | "TypeName": "Identifier"
25 | },
26 | {
27 | "Name": "b",
28 | "TypeName": "Identifier"
29 | }
30 | ],
31 | "TypeName": "Application"
32 | }
33 | ],
34 | "TypeName": "Body"
35 | },
36 | "TypeName": "Lambda"
37 | },
38 | "Operands": [
39 | {
40 | "Value": 1.0,
41 | "TypeName": "NumberLiteral"
42 | },
43 | {
44 | "Value": 2.0,
45 | "TypeName": "NumberLiteral"
46 | }
47 | ],
48 | "TypeName": "Application"
49 | }
50 | ]
51 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/46.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Parameters": [
6 | "a",
7 | "b"
8 | ],
9 | "Body": {
10 | "Definitions": [
11 | {
12 | "IdentifierName": "c",
13 | "Value": {
14 | "Value": 4.0,
15 | "TypeName": "NumberLiteral"
16 | },
17 | "TypeName": "Definition"
18 | }
19 | ],
20 | "Expressions": [
21 | {
22 | "Value": 1.0,
23 | "TypeName": "NumberLiteral"
24 | },
25 | {
26 | "Name": "a",
27 | "TypeName": "Identifier"
28 | },
29 | {
30 | "Name": "b",
31 | "TypeName": "Identifier"
32 | },
33 | {
34 | "Name": "c",
35 | "TypeName": "Identifier"
36 | },
37 | {
38 | "Operator": {
39 | "Name": "+",
40 | "TypeName": "Identifier"
41 | },
42 | "Operands": [
43 | {
44 | "Name": "a",
45 | "TypeName": "Identifier"
46 | },
47 | {
48 | "Name": "b",
49 | "TypeName": "Identifier"
50 | },
51 | {
52 | "Name": "c",
53 | "TypeName": "Identifier"
54 | }
55 | ],
56 | "TypeName": "Application"
57 | }
58 | ],
59 | "TypeName": "Body"
60 | },
61 | "TypeName": "Lambda"
62 | },
63 | "Operands": [
64 | {
65 | "Value": 1.0,
66 | "TypeName": "NumberLiteral"
67 | },
68 | {
69 | "Value": 2.0,
70 | "TypeName": "NumberLiteral"
71 | }
72 | ],
73 | "TypeName": "Application"
74 | }
75 | ]
76 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/48.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Predicate": {
5 | "Value": 1.0,
6 | "TypeName": "NumberLiteral"
7 | },
8 | "Consequent": {
9 | "Predicate": {
10 | "Value": 2.0,
11 | "TypeName": "NumberLiteral"
12 | },
13 | "Consequent": {
14 | "Predicate": {
15 | "Value": 3.0,
16 | "TypeName": "NumberLiteral"
17 | },
18 | "Consequent": {
19 | "Value": 4.0,
20 | "TypeName": "NumberLiteral"
21 | },
22 | "Alternative": {
23 | "Value": false,
24 | "TypeName": "BooleanLiteral"
25 | },
26 | "TypeName": "If"
27 | },
28 | "Alternative": {
29 | "Value": false,
30 | "TypeName": "BooleanLiteral"
31 | },
32 | "TypeName": "If"
33 | },
34 | "Alternative": {
35 | "Value": false,
36 | "TypeName": "BooleanLiteral"
37 | },
38 | "TypeName": "If"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/51.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Quotable": {
5 | "Text": "21.34",
6 | "Quotables": null
7 | },
8 | "TypeName": "Quote"
9 | }
10 | ]
11 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/52.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Quotable": {
5 | "Text": "\"hello world\"",
6 | "Quotables": null
7 | },
8 | "TypeName": "Quote"
9 | }
10 | ]
11 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/53.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Quotable": {
5 | "Text": "\"hello \\n \\t \\\\ \\\" world\"",
6 | "Quotables": null
7 | },
8 | "TypeName": "Quote"
9 | }
10 | ]
11 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/54.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Quotable": {
5 | "Text": "true",
6 | "Quotables": null
7 | },
8 | "TypeName": "Quote"
9 | }
10 | ]
11 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/55.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Quotable": {
5 | "Text": "false",
6 | "Quotables": null
7 | },
8 | "TypeName": "Quote"
9 | }
10 | ]
11 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/56.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Quotable": {
5 | "Text": null,
6 | "Quotables": []
7 | },
8 | "TypeName": "Quote"
9 | }
10 | ]
11 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/57.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Quotable": {
5 | "Text": null,
6 | "Quotables": [
7 | {
8 | "Text": "ab",
9 | "Quotables": null
10 | },
11 | {
12 | "Text": "cd",
13 | "Quotables": null
14 | }
15 | ]
16 | },
17 | "TypeName": "Quote"
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/58.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Quotable": {
5 | "Text": null,
6 | "Quotables": [
7 | {
8 | "Text": "ab",
9 | "Quotables": null
10 | },
11 | {
12 | "Text": "cd",
13 | "Quotables": null
14 | },
15 | {
16 | "Text": null,
17 | "Quotables": [
18 | {
19 | "Text": "e",
20 | "Quotables": null
21 | },
22 | {
23 | "Text": "f",
24 | "Quotables": null
25 | },
26 | {
27 | "Text": "g",
28 | "Quotables": null
29 | }
30 | ]
31 | },
32 | {
33 | "Text": "hi",
34 | "Quotables": null
35 | }
36 | ]
37 | },
38 | "TypeName": "Quote"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/59.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "IdentifierName": "a",
5 | "Value": {
6 | "Value": 1.0,
7 | "TypeName": "NumberLiteral"
8 | },
9 | "TypeName": "Definition"
10 | },
11 | {
12 | "IdentifierName": "a",
13 | "Value": {
14 | "Value": 2.0,
15 | "TypeName": "NumberLiteral"
16 | },
17 | "TypeName": "Assignment"
18 | },
19 | {
20 | "IdentifierName": "b",
21 | "Value": {
22 | "Name": "a",
23 | "TypeName": "Identifier"
24 | },
25 | "TypeName": "Definition"
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/60.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Delayed": {
5 | "Value": 1.0,
6 | "TypeName": "NumberLiteral"
7 | },
8 | "TypeName": "Delay"
9 | }
10 | ]
11 | }
--------------------------------------------------------------------------------
/RainLispTests/AbstractSyntaxTrees/61.json:
--------------------------------------------------------------------------------
1 | {
2 | "DefinitionsAndExpressions": [
3 | {
4 | "Operator": {
5 | "Name": "cons",
6 | "TypeName": "Identifier"
7 | },
8 | "Operands": [
9 | {
10 | "Value": 1.0,
11 | "TypeName": "NumberLiteral"
12 | },
13 | {
14 | "Delayed": {
15 | "Value": 2.0,
16 | "TypeName": "NumberLiteral"
17 | },
18 | "TypeName": "Delay"
19 | }
20 | ],
21 | "TypeName": "Application"
22 | }
23 | ]
24 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/00.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 0.0
5 | }
6 | },
7 | "nextEnvironments": []
8 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/01.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 0.0,
5 | "b": 1.0
6 | }
7 | },
8 | "nextEnvironments": []
9 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/02.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 0.0,
5 | "b": 1.0,
6 | "ab": 10.32
7 | }
8 | },
9 | "nextEnvironments": []
10 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/03.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 6.0,
5 | "ab": 4.0
6 | }
7 | },
8 | "nextEnvironments": []
9 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/04.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 4.0
5 | }
6 | },
7 | "nextEnvironments": [
8 | {
9 | "actualEnvironment": {
10 | "definitions": {}
11 | },
12 | "nextEnvironments": []
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/05.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 2.0
5 | }
6 | },
7 | "nextEnvironments": [
8 | {
9 | "actualEnvironment": {
10 | "definitions": {
11 | "b": 7.0
12 | }
13 | },
14 | "nextEnvironments": []
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/06.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 3.0
5 | }
6 | },
7 | "nextEnvironments": [
8 | {
9 | "actualEnvironment": {
10 | "definitions": {
11 | "b": 9.0
12 | }
13 | },
14 | "nextEnvironments": []
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/07.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 9.0
5 | }
6 | },
7 | "nextEnvironments": [
8 | {
9 | "actualEnvironment": {
10 | "definitions": {
11 | "b": 7.0
12 | }
13 | },
14 | "nextEnvironments": []
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/08.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 1.0
5 | }
6 | },
7 | "nextEnvironments": [
8 | {
9 | "actualEnvironment": {
10 | "definitions": {
11 | "b": 7.0
12 | }
13 | },
14 | "nextEnvironments": [
15 | {
16 | "actualEnvironment": {
17 | "definitions": {
18 | "c": 9.0
19 | }
20 | },
21 | "nextEnvironments": []
22 | }
23 | ]
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/09.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 2.0
5 | }
6 | },
7 | "nextEnvironments": [
8 | {
9 | "actualEnvironment": {
10 | "definitions": {
11 | "b": 3.0
12 | }
13 | },
14 | "nextEnvironments": [
15 | {
16 | "actualEnvironment": {
17 | "definitions": {
18 | "c": 4.0
19 | }
20 | },
21 | "nextEnvironments": []
22 | }
23 | ]
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/RainLispTests/Environments/10.json:
--------------------------------------------------------------------------------
1 | {
2 | "actualEnvironment": {
3 | "definitions": {
4 | "a": 1.0
5 | }
6 | },
7 | "nextEnvironments": [
8 | {
9 | "actualEnvironment": {
10 | "definitions": {
11 | "a": 2.0,
12 | "b": 7.0
13 | }
14 | },
15 | "nextEnvironments": [
16 | {
17 | "actualEnvironment": {
18 | "definitions": {
19 | "b": 8.0,
20 | "c": 9.0
21 | }
22 | },
23 | "nextEnvironments": []
24 | }
25 | ]
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/RainLispTests/TestDebugInfo.cs:
--------------------------------------------------------------------------------
1 | using RainLisp;
2 |
3 | namespace RainLispTests
4 | {
5 | internal class TestDebugInfo : IDebugInfo
6 | {
7 | public TestDebugInfo(uint line, uint position)
8 | {
9 | Line = line;
10 | Position = position;
11 | }
12 |
13 | public uint Line { get; set; }
14 |
15 | public uint Position { get; set; }
16 |
17 | public bool HasDebugInfo { get; set; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/RainLispTests/TestableEnvironmentContractResolver.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Newtonsoft.Json.Serialization;
3 | using RainLisp.Evaluation.Results;
4 | using System.Reflection;
5 |
6 | namespace RainLispTests
7 | {
8 | internal class TestableEnvironmentContractResolver : DefaultContractResolver
9 | {
10 | protected override IList CreateProperties(Type type, MemberSerialization memberSerialization)
11 | {
12 | // Do not serialize the internal structure of primitive procedures.
13 | if (type == typeof(PrimitiveProcedure))
14 | return new List();
15 |
16 | string valuePropName = nameof(PrimitiveDatum.Value);
17 | var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
18 |
19 | var props = type.GetProperties(flags)
20 | .Where(p => p.Name == valuePropName)
21 | .Select(p => base.CreateProperty(p, memberSerialization));
22 |
23 | var fields = type.GetFields(flags)
24 | .Select(f => base.CreateProperty(f, memberSerialization));
25 |
26 | var jsonProps = props.Concat(fields).ToList();
27 | foreach (var jsonProp in jsonProps)
28 | jsonProp.Readable = true;
29 |
30 | return jsonProps;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/RainLispTests/TestableEnvironmentFactory.cs:
--------------------------------------------------------------------------------
1 | using RainLisp.Evaluation;
2 |
3 | namespace RainLispTests
4 | {
5 | internal class TestableEnvironmentFactory : IEnvironmentFactory
6 | {
7 | public IEvaluationEnvironment CreateEnvironment()
8 | => new TestableEnvironment();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/RainLispTests/Usings.cs:
--------------------------------------------------------------------------------
1 | global using Xunit;
--------------------------------------------------------------------------------
/RainLispTests/Utils.cs:
--------------------------------------------------------------------------------
1 | namespace RainLispTests
2 | {
3 | internal static class Utils
4 | {
5 | internal static uint PickLine(uint winOS, uint otherOS)
6 | => Environment.NewLine == "\r\n" ? winOS : otherOS;
7 |
8 | internal static uint PickLine(uint winOS)
9 | => PickLine(winOS, winOS * 2 - 1);
10 |
11 | internal static string ReadAllTextOnAnyPlatform(string path)
12 | => File.ReadAllText(path).Replace("\r\n", Environment.NewLine);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/nuget.md:
--------------------------------------------------------------------------------
1 | # RainLisp
2 | 
3 | 
4 | 
5 |
6 | RainLisp is a programming language, belonging to the LISP family of languages, with many similarities to Scheme. It is implemented entirely in C# and therefore brought to the .NET ecosystem.
7 |
8 | It is not intended to replace your everyday programming language at work. Though, you can integrate it with your existing systems to allow for their configuration in terms of code.
9 |
10 | For example, one can build a system where parts of its computations or workflow logic is implemented in RainLisp. Its simplicity and capabilities make it ideal for using it like a DSL (Domain Specific Language) that integrates with your .NET system.
11 |
12 | Additionally, you can easily extend it to implement your own LISP dialect or replace some of its components, like the tokenizer and parser, and reuse the evaluator to easily build an entirely different but compatible programming language.
13 |
14 | You can also use it independently, using its code editor to learn LISP, play around with it and have fun!
15 |
16 | ## Documentation
17 | - [Tutorial](https://github.com/chr1st0scli/RainLisp/blob/master/RainLisp/Docs/quick-start.md)
18 | - [Specification](https://github.com/chr1st0scli/RainLisp/blob/master/RainLisp/Docs/contents.md)
19 | - [.NET Integration](https://github.com/chr1st0scli/RainLisp/blob/master/RainLisp/Docs/dotnet-integration.md)
20 |
21 | ## Tools
22 | - [RainLisp Console](https://github.com/chr1st0scli/RainLispConsole)
23 | - [RainLisp VSCode](https://marketplace.visualstudio.com/items?itemName=chr1st0scli.rainlisp-vscode)
24 |
--------------------------------------------------------------------------------