mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Add VuePress documentation subproject
This commit is contained in:
parent
bd836c868a
commit
2a45a30778
4
docs/.gitignore
vendored
Normal file
4
docs/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
.temp
|
||||
.cache
|
||||
/docs/*/modules/
|
43
docs/docs/.vuepress/config.js
Normal file
43
docs/docs/.vuepress/config.js
Normal file
@ -0,0 +1,43 @@
|
||||
import { defineUserConfig, defaultTheme } from 'vuepress'
|
||||
import { prismjsPlugin } from '@vuepress/plugin-prismjs'
|
||||
import { sidebarConfig } from './configs/sidebar'
|
||||
import { navbarConfig } from './configs/navbar'
|
||||
import Prism from 'prismjs';
|
||||
import definePrismOwnLang from '../../../editors/prismjs/own-language.js'
|
||||
definePrismOwnLang(Prism)
|
||||
|
||||
export default defineUserConfig({
|
||||
locales: {
|
||||
'/en/': {
|
||||
lang: 'en-US',
|
||||
title: 'OwnLang',
|
||||
description: 'OwnLang documentation',
|
||||
},
|
||||
'/ru/': {
|
||||
lang: 'ru-RU',
|
||||
title: 'OwnLang',
|
||||
description: 'Документация OwnLang',
|
||||
}
|
||||
},
|
||||
|
||||
theme: defaultTheme({
|
||||
locales: {
|
||||
'/en/': {
|
||||
selectLanguageName: 'English',
|
||||
sidebar: sidebarConfig.en,
|
||||
navbar: navbarConfig.en
|
||||
},
|
||||
'/ru/': {
|
||||
selectLanguageName: 'Русский',
|
||||
sidebar: sidebarConfig.ru,
|
||||
navbar: navbarConfig.ru
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
plugins: [
|
||||
prismjsPlugin({
|
||||
preloadLanguages: ['own', 'json']
|
||||
}),
|
||||
],
|
||||
})
|
16
docs/docs/.vuepress/configs/navbar.js
Normal file
16
docs/docs/.vuepress/configs/navbar.js
Normal file
@ -0,0 +1,16 @@
|
||||
import pages from './pages'
|
||||
|
||||
let navbar = {}
|
||||
for (let lang of ['en', 'ru']) {
|
||||
let config = []
|
||||
for (let [relativePath, entry] of Object.entries(pages)) {
|
||||
const path = '/' + lang + relativePath
|
||||
config.push({
|
||||
text: entry.text[lang],
|
||||
children: entry.pages.map(r => path + r)
|
||||
})
|
||||
}
|
||||
navbar[lang] = config
|
||||
}
|
||||
|
||||
export const navbarConfig = navbar
|
30
docs/docs/.vuepress/configs/pages.js
Normal file
30
docs/docs/.vuepress/configs/pages.js
Normal file
@ -0,0 +1,30 @@
|
||||
export default {
|
||||
'/': {
|
||||
text: {'en': 'OwnLang', 'ru': 'OwnLang'},
|
||||
pages: [
|
||||
'README.md',
|
||||
'links.md'
|
||||
]
|
||||
},
|
||||
|
||||
'/basics/': {
|
||||
text: {'en': 'Basics', 'ru': 'Основы'},
|
||||
pages: [
|
||||
'comments.md',
|
||||
'strings.md',
|
||||
'types.md',
|
||||
'loops.md',
|
||||
'functions.md',
|
||||
'destructuring_assignment.md',
|
||||
'pattern_matching.md',
|
||||
'string_functions.md',
|
||||
'array_functions.md'
|
||||
]
|
||||
},
|
||||
|
||||
'/modules/': {
|
||||
text: {'en': 'Modules', 'ru': 'Модули'},
|
||||
pages: [
|
||||
]
|
||||
}
|
||||
}
|
17
docs/docs/.vuepress/configs/sidebar.js
Normal file
17
docs/docs/.vuepress/configs/sidebar.js
Normal file
@ -0,0 +1,17 @@
|
||||
import pages from './pages'
|
||||
|
||||
let sidebar = {}
|
||||
for (let lang of ['en', 'ru']) {
|
||||
let config = {}
|
||||
for (let [relativePath, entry] of Object.entries(pages)) {
|
||||
const path = '/' + lang + relativePath
|
||||
config[path] = (path in config) ? config[path] : []
|
||||
config[path].push({
|
||||
text: entry.text[lang],
|
||||
children: entry.pages.map(r => path + r)
|
||||
})
|
||||
}
|
||||
sidebar[lang] = config
|
||||
}
|
||||
|
||||
export const sidebarConfig = sidebar
|
15
docs/docs/README.md
Normal file
15
docs/docs/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
home: true
|
||||
title: OwnLang
|
||||
heroText: OwnLang
|
||||
tagline: Dynamic functional programming language
|
||||
actions:
|
||||
- text: 🇺🇸 English
|
||||
link: /en/
|
||||
type: primary
|
||||
- text: 🇷🇺 Русский
|
||||
link: /ru/
|
||||
type: primary
|
||||
footer: © 2023 aNNiMON
|
||||
---
|
||||
|
5
docs/docs/code/basics/destructuring_assignment1.own
Normal file
5
docs/docs/code/basics/destructuring_assignment1.own
Normal file
@ -0,0 +1,5 @@
|
||||
arr = ["a", "b", "c"]
|
||||
extract(var1, var2, var3) = arr
|
||||
print var1 // a
|
||||
print var2 // b
|
||||
print var3 // c
|
4
docs/docs/code/basics/destructuring_assignment2.own
Normal file
4
docs/docs/code/basics/destructuring_assignment2.own
Normal file
@ -0,0 +1,4 @@
|
||||
arr = ["a", "b", "c"]
|
||||
var1 = arr[0]
|
||||
var2 = arr[1]
|
||||
var3 = arr[2]
|
4
docs/docs/code/basics/destructuring_assignment3.own
Normal file
4
docs/docs/code/basics/destructuring_assignment3.own
Normal file
@ -0,0 +1,4 @@
|
||||
map = {"key1": 1, "test", "text"}
|
||||
extract(var1, var2) = map
|
||||
println var1 // [key1, 1]
|
||||
println var2 // [test, text]
|
3
docs/docs/code/basics/destructuring_assignment4.own
Normal file
3
docs/docs/code/basics/destructuring_assignment4.own
Normal file
@ -0,0 +1,3 @@
|
||||
extract(x, , z) = [93, 58, 90]
|
||||
println x // 93
|
||||
println z // 90
|
9
docs/docs/code/basics/fibonacci.own
Normal file
9
docs/docs/code/basics/fibonacci.own
Normal file
@ -0,0 +1,9 @@
|
||||
def fibonacci(count) {
|
||||
def fib(n) {
|
||||
if n < 2 return n
|
||||
return fib(n-2) + fib(n-1)
|
||||
}
|
||||
return fib(count)
|
||||
}
|
||||
|
||||
println fibonacci(10) // 55
|
9
docs/docs/code/basics/loops1.own
Normal file
9
docs/docs/code/basics/loops1.own
Normal file
@ -0,0 +1,9 @@
|
||||
arr = [1, 2, 3, 4]
|
||||
for v : arr {
|
||||
println v
|
||||
}
|
||||
|
||||
map = {"key1": 1, "key2": 2}
|
||||
for key, value : map
|
||||
println key + " = " value
|
||||
}
|
7
docs/docs/code/basics/pattern_matching1.own
Normal file
7
docs/docs/code/basics/pattern_matching1.own
Normal file
@ -0,0 +1,7 @@
|
||||
x = 2
|
||||
print match x {
|
||||
case 1: "One"
|
||||
case 2: "Two"
|
||||
case "str": "String"
|
||||
case _: "Unknown"
|
||||
}
|
9
docs/docs/code/basics/pattern_matching2.own
Normal file
9
docs/docs/code/basics/pattern_matching2.own
Normal file
@ -0,0 +1,9 @@
|
||||
x = "str"
|
||||
match x {
|
||||
case "": {
|
||||
println "Empty string"
|
||||
}
|
||||
case "str": {
|
||||
println "String!"
|
||||
}
|
||||
}
|
10
docs/docs/code/basics/pattern_matching3.own
Normal file
10
docs/docs/code/basics/pattern_matching3.own
Normal file
@ -0,0 +1,10 @@
|
||||
def test(x) = match x {
|
||||
case a: "case a: " + a
|
||||
case b: "case b: " + b
|
||||
case c: "case c: " + c
|
||||
}
|
||||
a = 10
|
||||
b = 20
|
||||
println test(15) // case c: 15
|
||||
println test(20) // case b: 20
|
||||
println test("test") // case c: test
|
9
docs/docs/code/basics/pattern_matching4.own
Normal file
9
docs/docs/code/basics/pattern_matching4.own
Normal file
@ -0,0 +1,9 @@
|
||||
def test(x) = match x {
|
||||
case x if x < 0: "(-∞ .. 0)"
|
||||
case x if x > 0: "(0 .. +∞)"
|
||||
case x: "0"
|
||||
}
|
||||
|
||||
println test(-10) // (-∞ .. 0)
|
||||
println test(0) // 0
|
||||
println test(10) // (0 .. +∞)
|
7
docs/docs/code/basics/pattern_matching5.own
Normal file
7
docs/docs/code/basics/pattern_matching5.own
Normal file
@ -0,0 +1,7 @@
|
||||
def arrayRecursive(arr) = match arr {
|
||||
case [head :: tail]: "[" + head + ", " + arrayRecursive(tail) + "]"
|
||||
case []: "[]"
|
||||
case last: "[" + last + ", []]"
|
||||
}
|
||||
|
||||
println arrayRecursive([1, 2, 3, 4, 5, 6, 7]) // [1, [2, [3, [4, [5, [6, [7, []]]]]]]]
|
8
docs/docs/code/basics/pattern_matching6.own
Normal file
8
docs/docs/code/basics/pattern_matching6.own
Normal file
@ -0,0 +1,8 @@
|
||||
for i = 1, i <= 100, i++ {
|
||||
println match [i % 3 == 0, i % 5 == 0] {
|
||||
case (true, false): "Fizz"
|
||||
case (false, true): "Buzz"
|
||||
case (true, true): "FizzBuzz"
|
||||
case _: i
|
||||
}
|
||||
}
|
7
docs/docs/code/basics/string_functions1.own
Normal file
7
docs/docs/code/basics/string_functions1.own
Normal file
@ -0,0 +1,7 @@
|
||||
str = " ababcaab "
|
||||
println indexOf(str, "abc")
|
||||
println str.indexOf("abc")
|
||||
|
||||
def isBlank(s) = s.trim().isEmpty()
|
||||
println isBlank(str)
|
||||
println str.isBlank()
|
15
docs/docs/code/functional_en.own
Normal file
15
docs/docs/code/functional_en.own
Normal file
@ -0,0 +1,15 @@
|
||||
use std, functional
|
||||
|
||||
nums = [1,2,3,4,5,6,7,8,9,10]
|
||||
nums = filter(nums, def(x) = x % 2 == 0)
|
||||
// Squares of even numbers
|
||||
squares = map(nums, def(x) = x * x)
|
||||
foreach(squares, ::echo)
|
||||
// Sum of squares
|
||||
sum = reduce(squares, 0, def(x, y) = x + y)
|
||||
println "Sum: " + sum
|
||||
// Same using stream
|
||||
println "Sum: " + stream(range(1, 11))
|
||||
.filter(def(x) = x % 2 == 0)
|
||||
.map(def(x) = x * x)
|
||||
.reduce(0, def(x, y) = x + y)
|
15
docs/docs/code/functional_ru.own
Normal file
15
docs/docs/code/functional_ru.own
Normal file
@ -0,0 +1,15 @@
|
||||
use std, functional
|
||||
|
||||
nums = [1,2,3,4,5,6,7,8,9,10]
|
||||
nums = filter(nums, def(x) = x % 2 == 0)
|
||||
// Квадраты чётных чисел
|
||||
squares = map(nums, def(x) = x * x)
|
||||
foreach(squares, ::echo)
|
||||
// Сумма квадратов
|
||||
sum = reduce(squares, 0, def(x, y) = x + y)
|
||||
println "Сумма: " + sum
|
||||
// То же самое с использованием stream
|
||||
println "Сумма: " + stream(range(1, 11))
|
||||
.filter(def(x) = x % 2 == 0)
|
||||
.map(def(x) = x * x)
|
||||
.reduce(0, def(x, y) = x + y)
|
14
docs/docs/code/high_order_functions_en.own
Normal file
14
docs/docs/code/high_order_functions_en.own
Normal file
@ -0,0 +1,14 @@
|
||||
operations = {
|
||||
"+" : def(a,b) = a+b,
|
||||
"-" : def(a,b) = a-b,
|
||||
"*" : def(a,b) = a*b,
|
||||
"/" : ::division
|
||||
}
|
||||
def division(v1, v2) {
|
||||
if (v2 == 0) return "error: division by zero"
|
||||
return v1 / v2
|
||||
}
|
||||
|
||||
for operation : operations {
|
||||
println operation(2, 3)
|
||||
}
|
14
docs/docs/code/high_order_functions_ru.own
Normal file
14
docs/docs/code/high_order_functions_ru.own
Normal file
@ -0,0 +1,14 @@
|
||||
operations = {
|
||||
"+" : def(a,b) = a+b,
|
||||
"-" : def(a,b) = a-b,
|
||||
"*" : def(a,b) = a*b,
|
||||
"/" : ::division
|
||||
}
|
||||
def division(v1, v2) {
|
||||
if (v2 == 0) return "ошибка: деление на ноль"
|
||||
return v1 / v2
|
||||
}
|
||||
|
||||
for operation : operations {
|
||||
println operation(2, 3)
|
||||
}
|
20
docs/docs/code/http_en.own
Normal file
20
docs/docs/code/http_en.own
Normal file
@ -0,0 +1,20 @@
|
||||
use std, http, functional
|
||||
|
||||
// GET request
|
||||
http("https://api.github.com/events", def(r) {
|
||||
use json
|
||||
events = jsondecode(r)
|
||||
})
|
||||
|
||||
// POST request
|
||||
http("http://jsonplaceholder.typicode.com/users", "POST", {
|
||||
"name": "OwnLang",
|
||||
"versionCode": 10
|
||||
}, ::echo)
|
||||
|
||||
// PATCH request
|
||||
http("http://jsonplaceholder.typicode.com/users/2", "PATCH", {"name": "Patched Name"}, ::patch_callback)
|
||||
|
||||
def patch_callback(v) {
|
||||
println v
|
||||
}
|
20
docs/docs/code/http_ru.own
Normal file
20
docs/docs/code/http_ru.own
Normal file
@ -0,0 +1,20 @@
|
||||
use std, http, functional
|
||||
|
||||
// GET-запрос
|
||||
http("https://api.github.com/events", def(r) {
|
||||
use json
|
||||
events = jsondecode(r)
|
||||
})
|
||||
|
||||
// POST-запрос
|
||||
http("http://jsonplaceholder.typicode.com/users", "POST", {
|
||||
"name": "OwnLang",
|
||||
"versionCode": 10
|
||||
}, ::echo)
|
||||
|
||||
// PATCH-запрос
|
||||
http("http://jsonplaceholder.typicode.com/users/2", "PATCH", {"name": "Патч"}, ::patch_callback)
|
||||
|
||||
def patch_callback(v) {
|
||||
println v
|
||||
}
|
7
docs/docs/code/operator_overloading.own
Normal file
7
docs/docs/code/operator_overloading.own
Normal file
@ -0,0 +1,7 @@
|
||||
use std, types, math
|
||||
|
||||
def `..`(a, b) = range(a, b - 1)
|
||||
def `**`(a, b) = int(pow(a, b))
|
||||
for y : 1 .. 10 {
|
||||
println sprintf("2 ^ %d = %d", y, 2 ** y)
|
||||
}
|
16
docs/docs/code/pattern_matching.own
Normal file
16
docs/docs/code/pattern_matching.own
Normal file
@ -0,0 +1,16 @@
|
||||
def factorial(n) = match n {
|
||||
case 0: 1
|
||||
case n if n < 0: 0
|
||||
case _: n * factorial(n - 1)
|
||||
}
|
||||
|
||||
def fizzbuzz(limit = 100) {
|
||||
for i = 1, i <= limit, i++ {
|
||||
println match [i % 3 == 0, i % 5 == 0] {
|
||||
case (true, false): "Fizz"
|
||||
case (false, true): "Buzz"
|
||||
case (true, true): "FizzBuzz"
|
||||
case _: i
|
||||
}
|
||||
}
|
||||
}
|
35
docs/docs/en/README.md
Normal file
35
docs/docs/en/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Overview
|
||||
|
||||
OwnLang — dynamic functional programming language inspired by Scala and Python. Available for PC and Android devices.
|
||||
|
||||
## Key features
|
||||
|
||||
### Higher-order functions
|
||||
|
||||
Functions are values, so we can store them to variables for operating.
|
||||
|
||||
@[code](../code/high_order_functions_en.own)
|
||||
|
||||
### Pattern Matching
|
||||
|
||||
Pattern matching with value pattern, tuple pattern, list pattern and optional condition.
|
||||
|
||||
@[code](../code/pattern_matching.own)
|
||||
|
||||
### Functional data operations
|
||||
|
||||
Operate data in functional style.
|
||||
|
||||
@[code](../code/functional_en.own)
|
||||
|
||||
### Operator overloading
|
||||
|
||||
Why not?
|
||||
|
||||
@[code](../code/operator_overloading.own)
|
||||
|
||||
### Network module
|
||||
|
||||
Easy async HTTP requests with `http` module.
|
||||
|
||||
@[code](../code/http_en.own)
|
11
docs/docs/en/basics/README.md
Normal file
11
docs/docs/en/basics/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Basics
|
||||
|
||||
* [Comments](comments.md)
|
||||
* [Strings](strings.md)
|
||||
* [Types](types.md)
|
||||
* [Loops](loops.md)
|
||||
* [Functions definition](functions.md)
|
||||
* [Destructuring assignment](destructuring_assignment.md)
|
||||
* [Pattern matching](pattern_matching.md)
|
||||
* [String functions](string_functions.md)
|
||||
* [Array functions](array_functions.md)
|
8
docs/docs/en/basics/array_functions.md
Normal file
8
docs/docs/en/basics/array_functions.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Array functions
|
||||
|
||||
Fields:
|
||||
- `length` - number of elements of the array
|
||||
|
||||
Functions:
|
||||
- `isEmpty()` - returns true, if the array is empty
|
||||
- `joinToString(delimiter = "", prefix = "", suffix = "")` - joins array into a string
|
9
docs/docs/en/basics/comments.md
Normal file
9
docs/docs/en/basics/comments.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Comments
|
||||
|
||||
```own
|
||||
// Line comment
|
||||
/* multiline
|
||||
comment
|
||||
*/
|
||||
print /*inner comment*/ "Text"
|
||||
```
|
19
docs/docs/en/basics/destructuring_assignment.md
Normal file
19
docs/docs/en/basics/destructuring_assignment.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Destructuring assignment
|
||||
|
||||
Destructuring assignment allows to define multiple variables for each element of an array or map.
|
||||
|
||||
For arrays, value is assigned to variable:
|
||||
|
||||
@[code](../../code/basics/destructuring_assignment1.own)
|
||||
|
||||
Which is equivalent to:
|
||||
|
||||
@[code](../../code/basics/destructuring_assignment2.own)
|
||||
|
||||
For maps, key and value are assigned to variable:
|
||||
|
||||
@[code](../../code/basics/destructuring_assignment3.own)
|
||||
|
||||
To skip value just leave argument empty:
|
||||
|
||||
@[code](../../code/basics/destructuring_assignment4.own)
|
54
docs/docs/en/basics/functions.md
Normal file
54
docs/docs/en/basics/functions.md
Normal file
@ -0,0 +1,54 @@
|
||||
# Functions definition
|
||||
|
||||
To define function uses the `def` keyword:
|
||||
|
||||
```own
|
||||
def function(arg1, arg2) {
|
||||
println arg1
|
||||
}
|
||||
```
|
||||
|
||||
## Shorthand definition
|
||||
|
||||
There is short syntax fot function body:
|
||||
|
||||
```own
|
||||
def repeat(str, count) = str * count
|
||||
```
|
||||
|
||||
Which is equivalent to:
|
||||
|
||||
```own
|
||||
def repeat(str, count) {
|
||||
return str * count
|
||||
}
|
||||
```
|
||||
|
||||
## Default arguments
|
||||
|
||||
Function arguments can have default values.
|
||||
|
||||
```own
|
||||
def repeat(str, count = 5) = str * count
|
||||
```
|
||||
|
||||
In this case only `str` argument is required.
|
||||
|
||||
```own
|
||||
repeat("*") // *****
|
||||
repeat("+", 3) // +++
|
||||
```
|
||||
|
||||
Default arguments can't be declared before required arguments.
|
||||
|
||||
```own
|
||||
def repeat(str = "*", count) = str * count
|
||||
```
|
||||
|
||||
Causes parsing error: `ParseError on line 1: Required argument cannot be after optional`
|
||||
|
||||
## Inner functions
|
||||
|
||||
You can define function in other function.
|
||||
|
||||
@[code](../../code/basics/fibonacci.own)
|
113
docs/docs/en/basics/loops.md
Normal file
113
docs/docs/en/basics/loops.md
Normal file
@ -0,0 +1,113 @@
|
||||
# Loops
|
||||
|
||||
## while loop
|
||||
|
||||
```own
|
||||
while condition {
|
||||
body
|
||||
}
|
||||
```
|
||||
|
||||
Parentheses in condition are not necessary.
|
||||
|
||||
```own
|
||||
i = 0
|
||||
while i < 5 {
|
||||
print i++
|
||||
}
|
||||
|
||||
// or
|
||||
|
||||
i = 0
|
||||
while (i < 5) {
|
||||
print i++
|
||||
}
|
||||
```
|
||||
|
||||
## do-while loop
|
||||
|
||||
```own
|
||||
do {
|
||||
body
|
||||
} while condition
|
||||
```
|
||||
|
||||
Parentheses in condition are not necessary.
|
||||
|
||||
```own
|
||||
i = 0
|
||||
do {
|
||||
print i++
|
||||
} while i < 5
|
||||
|
||||
// or
|
||||
|
||||
i = 0
|
||||
do {
|
||||
print i++
|
||||
} while (i < 5)
|
||||
```
|
||||
|
||||
## for loop
|
||||
|
||||
```own
|
||||
for initializing, condition, increment {
|
||||
body
|
||||
}
|
||||
|
||||
for (initializing, condition, increment) {
|
||||
body
|
||||
}
|
||||
```
|
||||
|
||||
```own
|
||||
for i = 0, i < 5, i++
|
||||
print i++
|
||||
|
||||
// or
|
||||
|
||||
for (i = 0, i < 5, i++) {
|
||||
print i++
|
||||
}
|
||||
```
|
||||
|
||||
## foreach loop
|
||||
|
||||
Iterates elements of an string, array or map.
|
||||
|
||||
Iterating over string:
|
||||
|
||||
```own
|
||||
for char : string {
|
||||
body
|
||||
}
|
||||
for char, code : string {
|
||||
body
|
||||
}
|
||||
```
|
||||
|
||||
Iterating over array:
|
||||
|
||||
```own
|
||||
for value : array {
|
||||
body
|
||||
}
|
||||
for value, index : array {
|
||||
body
|
||||
}
|
||||
```
|
||||
|
||||
Iterating over map:
|
||||
|
||||
```own
|
||||
for key, value : map {
|
||||
body
|
||||
}
|
||||
for (key, value : map) {
|
||||
body
|
||||
}
|
||||
```
|
||||
|
||||
Parentheses are not necessary.
|
||||
|
||||
@[code](../../code/basics/loops1.own)
|
79
docs/docs/en/basics/pattern_matching.md
Normal file
79
docs/docs/en/basics/pattern_matching.md
Normal file
@ -0,0 +1,79 @@
|
||||
# Pattern matching
|
||||
|
||||
The `match` operator allows to match values by pattern.
|
||||
|
||||
@[code](../../code/basics/pattern_matching1.own)
|
||||
|
||||
@[code](../../code/basics/pattern_matching2.own)
|
||||
|
||||
In this case value and type are checking. If none of `case` branches doesn't match, the body of `case _` branch will executes.
|
||||
|
||||
|
||||
In addition to the constant values, you can set variable name to `case`.
|
||||
|
||||
@[code](../../code/basics/pattern_matching3.own)
|
||||
|
||||
In this case there is two scenarios:
|
||||
|
||||
1. Variable is already defined. Matching to its value.
|
||||
2. Variable is not defined. Assign matching value to it and executes body of the `case` branch.
|
||||
|
||||
In the example above, the interpreter sees the first two branches as:
|
||||
|
||||
```own
|
||||
case 10:
|
||||
case 20:
|
||||
```
|
||||
|
||||
For the last branch `c` variable is not defined, so assign `c = x` and execute body of the `case c` branch.
|
||||
|
||||
|
||||
## Refinements
|
||||
|
||||
`case` branch may have additional comparison
|
||||
|
||||
@[code](../../code/basics/pattern_matching4.own)
|
||||
|
||||
|
||||
## Matching arrays
|
||||
|
||||
To compare elements of arrays, the following syntax is used:
|
||||
|
||||
* `case []:` executes if there are no elements in array
|
||||
* `case [a]:` executes if an array contains one element
|
||||
* `case [a :: b]:` executes if an array contains two or more elements
|
||||
* `case [a :: b :: c :: d :: e]:` executes if an array contain five or more elements
|
||||
|
||||
There are two rules for the last two cases:
|
||||
|
||||
* If variables count matches array elements count - all variables are assigned to the value of the array.
|
||||
|
||||
```own
|
||||
match [0, 1, 2] {
|
||||
case [x :: y :: z]: // x = 0, y = 1, z = 2
|
||||
}
|
||||
```
|
||||
|
||||
* If array elements count is greater, then the rest of the array will be assigned to the last variable.
|
||||
|
||||
```own
|
||||
match [0, 1, 2, 3, 4] {
|
||||
case [x :: y :: z]: // x = 0, y = 1, z = [2, 3, 4]
|
||||
}
|
||||
```
|
||||
|
||||
An example of a recursive output array
|
||||
|
||||
@[code](../../code/basics/pattern_matching5.own)
|
||||
|
||||
|
||||
## Matching array's value
|
||||
|
||||
To compare values of array's elements, the following syntax is used:
|
||||
|
||||
* `case (expr1, expr2, expr3):` executes if an array contain 3 elements and first element is equal to expr1 result, second element is equal to expr2 and third element is equal to expr3.
|
||||
* `case (expr1, _):` executes if an array contain 2 elements and first element is equal to expr1 result and result of the second element is not importand.
|
||||
|
||||
FizzBuzz classical problem can be solved using Pattern Matching:
|
||||
|
||||
@[code](../../code/basics/pattern_matching6.own)
|
20
docs/docs/en/basics/string_functions.md
Normal file
20
docs/docs/en/basics/string_functions.md
Normal file
@ -0,0 +1,20 @@
|
||||
# String functions
|
||||
|
||||
Fields:
|
||||
- `length` - string length
|
||||
- `lower` - lower case string
|
||||
- `upper` - upper case string
|
||||
- `chars` - ASCII characters array
|
||||
|
||||
Functions:
|
||||
- `trim()` - removes any leading and trailing whitespaces in string
|
||||
- `startsWith(str, offset = 0)` - checks whether the string starts with the substring str at offset
|
||||
- `endsWith(str)` - checks whether the string ends with the str
|
||||
- `matches(regex)` - checks whether the string matches regex pattern
|
||||
- `contains(str)` - checks whether the string contains substring str
|
||||
- `equalsIgnoreCase(str)` - checks equality of two strings ignore case (tEsT = TEST)
|
||||
- `isEmpty()` - returns true, if the string is empty
|
||||
|
||||
In addition, there are automatic function extensions available if the function accepts a string as the first argument:
|
||||
|
||||
@[code](../../code/basics/string_functions1.own)
|
12
docs/docs/en/basics/strings.md
Normal file
12
docs/docs/en/basics/strings.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Strings
|
||||
|
||||
Strings are defined in double quotes and can be multiline. Escaping Unicode characters is also supported.:
|
||||
|
||||
```own
|
||||
str = "\n\tThis is
|
||||
\tmultiline
|
||||
\ttext
|
||||
"
|
||||
```
|
||||
|
||||
`print` and `println` operators are used to output text.
|
24
docs/docs/en/basics/types.md
Normal file
24
docs/docs/en/basics/types.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Types
|
||||
|
||||
OwnLang types are:
|
||||
|
||||
* Number - numbers (integer, float)
|
||||
* String - strings
|
||||
* Array - arrays
|
||||
* Map - objects (an associative arrays)
|
||||
* Function - functions
|
||||
|
||||
Since OwnLang is dynamic programming language, which means that explicitly declare the types is not necessary.
|
||||
|
||||
```own
|
||||
x = 10 // integer
|
||||
y = 1.61803 // float
|
||||
z = "abcd" // string
|
||||
```
|
||||
|
||||
If some function requires string as argument, but number was passed, then numeric value will automatically converts to string.
|
||||
|
||||
```own
|
||||
x = 90
|
||||
print x // Ok, 90 converts to "90"
|
||||
```
|
13
docs/docs/en/links.md
Normal file
13
docs/docs/en/links.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Links
|
||||
|
||||
## Downloads
|
||||
|
||||
Android: [Free](https://play.google.com/store/apps/details?id=com.annimon.ownlang.free) / [Pro](https://play.google.com/store/apps/details?id=com.annimon.ownlang)
|
||||
PC / Netbeans Plugin / etc: [GitHub Releases](https://github.com/aNNiMON/Own-Programming-Language-Tutorial/releases)
|
||||
Source code: [GitHub](https://github.com/aNNiMON/Own-Programming-Language-Tutorial)
|
||||
|
||||
Also available as AUR package:
|
||||
|
||||
```
|
||||
paru -S ownlang
|
||||
```
|
35
docs/docs/ru/README.md
Normal file
35
docs/docs/ru/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Возможности
|
||||
|
||||
OwnLang — скриптовый функциональный язык программирования с динамической типизацией для ПК и Android устройств.
|
||||
|
||||
## Ключевые особенности
|
||||
|
||||
### Функции высшего порядка
|
||||
|
||||
Функции выступают как значения, а значит мы можем сохранять их в переменные для дальнейшего использования.
|
||||
|
||||
@[code](../code/high_order_functions_ru.own)
|
||||
|
||||
### Pattern Matching
|
||||
|
||||
Сопоставление по образцу с шаблоном значений, шаблоном кортежей, шаблоном списков и дополнительным сравнением.
|
||||
|
||||
@[code](../code/pattern_matching.own)
|
||||
|
||||
### Функциональные операции над данными
|
||||
|
||||
Оперирование данными в функциональном стиле.
|
||||
|
||||
@[code](../code/functional_ru.own)
|
||||
|
||||
### Перегрузка операторов
|
||||
|
||||
Почему бы и нет?
|
||||
|
||||
@[code](../code/operator_overloading.own)
|
||||
|
||||
### Модуль для работы с сетью Интернет
|
||||
|
||||
Простые асинхронные HTTP-запросы с модулем `http`.
|
||||
|
||||
@[code](../code/http_ru.own)
|
11
docs/docs/ru/basics/README.md
Normal file
11
docs/docs/ru/basics/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Синтаксис и основы языка
|
||||
|
||||
* [Комментарии](comments.md)
|
||||
* [Строки](strings.md)
|
||||
* [Типы](types.md)
|
||||
* [Циклы](loops.md)
|
||||
* [Определение функций](functions.md)
|
||||
* [Реструктуризующее присваивание](destructuring_assignment.md)
|
||||
* [Pattern matching](pattern_matching.md) (сопоставление с образцом)
|
||||
* [Функции строк](string_functions.md)
|
||||
* [Функции массивов](array_functions.md)
|
8
docs/docs/ru/basics/array_functions.md
Normal file
8
docs/docs/ru/basics/array_functions.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Функции массивов
|
||||
|
||||
Поля:
|
||||
- `length` - количество элементов массива
|
||||
|
||||
Функции:
|
||||
- `isEmpty()` - возвращает true, если массив пуст
|
||||
- `joinToString(delimiter = "", prefix = "", suffix = "")` - склеивает массив в строку
|
9
docs/docs/ru/basics/comments.md
Normal file
9
docs/docs/ru/basics/comments.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Комментарии
|
||||
|
||||
```own
|
||||
// Однострочный комментарий
|
||||
/* многострочный
|
||||
комментарий
|
||||
*/
|
||||
print /*или так*/ "Текст"
|
||||
```
|
19
docs/docs/ru/basics/destructuring_assignment.md
Normal file
19
docs/docs/ru/basics/destructuring_assignment.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Реструктуризующее присваивание
|
||||
|
||||
Реструктуризующее (деструктивное) присваивание позволяет определить сразу несколько переменных по каждому элементу массива или объекта.
|
||||
|
||||
Для массивов, переменным присваивается значение.
|
||||
|
||||
@[code](../../code/basics/destructuring_assignment1.own)
|
||||
|
||||
Что равносильно:
|
||||
|
||||
@[code](../../code/basics/destructuring_assignment2.own)
|
||||
|
||||
Для объектов, переменным присваивается массив [ключ, значение]
|
||||
|
||||
@[code](../../code/basics/destructuring_assignment3.own)
|
||||
|
||||
Если нужно пропустить какое-либо значение, название переменной можно не писать:
|
||||
|
||||
@[code](../../code/basics/destructuring_assignment4.own)
|
54
docs/docs/ru/basics/functions.md
Normal file
54
docs/docs/ru/basics/functions.md
Normal file
@ -0,0 +1,54 @@
|
||||
# Определение функций
|
||||
|
||||
Для определения функции используется ключевое слово `def`. Затем идёт имя, аргументы и тело функции. Пример:
|
||||
|
||||
```own
|
||||
def function(arg1, arg2) {
|
||||
println arg1
|
||||
}
|
||||
```
|
||||
|
||||
## Короткий синтаксис
|
||||
|
||||
Возможен короткий синтаксис:
|
||||
|
||||
```own
|
||||
def repeat(str, count) = str * count
|
||||
```
|
||||
|
||||
что равносильно:
|
||||
|
||||
```own
|
||||
def repeat(str, count) {
|
||||
return str * count
|
||||
}
|
||||
```
|
||||
|
||||
## Аргументы по умолчанию
|
||||
|
||||
Аргументы функции могут иметь значения по умолчанию.
|
||||
|
||||
```own
|
||||
def repeat(str, count = 5) = str * count
|
||||
```
|
||||
|
||||
В этом случае обязательным будет только аргумент `str`
|
||||
|
||||
```own
|
||||
repeat("*") // *****
|
||||
repeat("+", 3) // +++
|
||||
```
|
||||
|
||||
Аргументы по умолчанию обязательно должны идти после обязательных аргументов, если такие были.
|
||||
|
||||
```own
|
||||
def repeat(str = "*", count) = str * count
|
||||
```
|
||||
|
||||
Приведёт к ошибки парсинга: `ParseError on line 1: Required argument cannot be after optional`
|
||||
|
||||
## Внутренние функции
|
||||
|
||||
Внутри функции можно объявить другую функцию.
|
||||
|
||||
@[code](../../code/basics/fibonacci.own)
|
115
docs/docs/ru/basics/loops.md
Normal file
115
docs/docs/ru/basics/loops.md
Normal file
@ -0,0 +1,115 @@
|
||||
# Циклы
|
||||
|
||||
## Цикл while
|
||||
|
||||
```own
|
||||
while условие {
|
||||
тело цикла
|
||||
}
|
||||
```
|
||||
|
||||
Скобки в условии необязательны.
|
||||
|
||||
```own
|
||||
i = 0
|
||||
while i < 5 {
|
||||
print i++
|
||||
}
|
||||
|
||||
// или
|
||||
|
||||
i = 0
|
||||
while (i < 5) {
|
||||
print i++
|
||||
}
|
||||
```
|
||||
|
||||
## Цикл do-while
|
||||
|
||||
```own
|
||||
do {
|
||||
тело цикла
|
||||
} while условие
|
||||
```
|
||||
|
||||
Скобки в условии необязательны.
|
||||
|
||||
```own
|
||||
i = 0
|
||||
do {
|
||||
print i++
|
||||
} while i < 5
|
||||
|
||||
// или
|
||||
|
||||
i = 0
|
||||
do {
|
||||
print i++
|
||||
} while (i < 5)
|
||||
```
|
||||
|
||||
## Цикл for
|
||||
|
||||
```own
|
||||
for инициализация, условие_работы, инкремент {
|
||||
тело цикла
|
||||
}
|
||||
|
||||
for (инициализация, условие_работы, инкремент) {
|
||||
тело цикла
|
||||
}
|
||||
```
|
||||
|
||||
Скобки в условии необязательны.
|
||||
|
||||
```own
|
||||
for i = 0, i < 5, i++
|
||||
print i++
|
||||
|
||||
// или
|
||||
|
||||
for (i = 0, i < 5, i++) {
|
||||
print i++
|
||||
}
|
||||
```
|
||||
|
||||
## Цикл foreach
|
||||
|
||||
Перебирает элементы строки, массива или карты.
|
||||
|
||||
Перебор строки:
|
||||
|
||||
```own
|
||||
for символ : строка {
|
||||
тело цикла
|
||||
}
|
||||
for символ, код : строка {
|
||||
тело цикла
|
||||
}
|
||||
```
|
||||
|
||||
Перебор массива:
|
||||
|
||||
```own
|
||||
for значение : массив {
|
||||
тело цикла
|
||||
}
|
||||
for значение, индекс : массив {
|
||||
тело цикла
|
||||
}
|
||||
for (значение : массив) {
|
||||
тело цикла
|
||||
}
|
||||
```
|
||||
|
||||
Перебор карты:
|
||||
|
||||
```own
|
||||
for (ключ, значение : карта) {
|
||||
тело цикла
|
||||
}
|
||||
```
|
||||
|
||||
Скобки необязательны.
|
||||
|
||||
@[code](../../code/basics/loops1.own)
|
79
docs/docs/ru/basics/pattern_matching.md
Normal file
79
docs/docs/ru/basics/pattern_matching.md
Normal file
@ -0,0 +1,79 @@
|
||||
# Pattern Matching (сопоставление с образцом)
|
||||
|
||||
Оператор `match` позволяет выполнить сопоставление значения с образцом.
|
||||
|
||||
@[code](../../code/basics/pattern_matching1.own)
|
||||
|
||||
@[code](../../code/basics/pattern_matching2.own)
|
||||
|
||||
Проверяется тип и значение. Если ни одна из веток `case` не обнаружила совпадение, выполняется тело ветки `case _`.
|
||||
|
||||
|
||||
Помимо константных значений, в `case` может присутствовать имя переменной.
|
||||
|
||||
@[code](../../code/basics/pattern_matching3.own)
|
||||
|
||||
В таком случае возможен один из двух сценариев:
|
||||
|
||||
1. Переменная уже определена. Сравнивается её значение.
|
||||
2. Переменная не определена. Ей присваивается сопоставляемое значение и выполняется ветка `case`.
|
||||
|
||||
В примере выше, интерпретатор видит первые две ветки так:
|
||||
|
||||
```own
|
||||
case 10:
|
||||
case 20:
|
||||
```
|
||||
|
||||
Для последней ветки переменная `c` не определена, поэтому выполнится присваивание `c = x`, после чего вызов передаётся телу ветки `case c`.
|
||||
|
||||
|
||||
## Уточнения
|
||||
|
||||
Ветка `case` может иметь дополнительное сравнение
|
||||
|
||||
@[code](../../code/basics/pattern_matching4.own)
|
||||
|
||||
|
||||
## Сопоставление массивов
|
||||
|
||||
Для сопоставления элементов массивов, в блоке case используется следующий синтаксис:
|
||||
|
||||
* `case []:` выполняется, если в массиве нет элементов
|
||||
* `case [a]:` выполняется, если в массиве есть один элемент
|
||||
* `case [a :: b]:` выполняется, если в массиве есть два и более элементов
|
||||
* `case [a :: b :: c :: d :: e]:` выполняется, если в массиве есть пять и более элементов
|
||||
|
||||
Для двух последних случаев справедливы такие правила:
|
||||
|
||||
* Если количество переменных в списке совпадает с количество элементов массива, то всем переменным присваивается значение массива.
|
||||
|
||||
```own
|
||||
match [0, 1, 2] {
|
||||
case [x :: y :: z]: // x = 0, y = 1, z = 2
|
||||
}
|
||||
```
|
||||
|
||||
* Если элементов массива больше, то в последней переменной будут сохранены оставшиеся элементы массива.
|
||||
|
||||
```own
|
||||
match [0, 1, 2, 3, 4] {
|
||||
case [x :: y :: z]: // x = 0, y = 1, z = [2, 3, 4]
|
||||
}
|
||||
```
|
||||
|
||||
Пример рекурсивного вывода элементов массива
|
||||
|
||||
@[code](../../code/basics/pattern_matching5.own)
|
||||
|
||||
|
||||
## Сопоставление значений массивов
|
||||
|
||||
Для сопоставления значений элементов массивов, используется синтаксис:
|
||||
|
||||
* `case (expr1, expr2, expr3):` выполняется, если в массиве есть 3 элемента и первый элемент равен результату выражения expr1, второй - результату expr2 и третий - результату expr3.
|
||||
* `case (expr1, _):` выполняется, если в массиве есть 2 элемента и первый элемент равен результату выражения expr1, а результат второго не важен.
|
||||
|
||||
Классическая задача FizzBuzz может быть решена с использованием Pattern Matching:
|
||||
|
||||
@[code](../../code/basics/pattern_matching6.own)
|
20
docs/docs/ru/basics/string_functions.md
Normal file
20
docs/docs/ru/basics/string_functions.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Функции строк
|
||||
|
||||
Поля:
|
||||
- `length` - длина строки
|
||||
- `lower` - строка в нижнем регистре
|
||||
- `upper` - строка в верхнем регистре
|
||||
- `chars` - массив символов в виде ASCII-кодов
|
||||
|
||||
Функции:
|
||||
- `trim()` - обрезает пробельные невидимые символы по обоим концам строки
|
||||
- `startsWith(str, offset = 0)` - проверяет, начинается ли строка с подстроки str в позиции offset
|
||||
- `endsWith(str)` - проверяет, заканчивается ли строка подстрокой str
|
||||
- `matches(regex)` - проверяет соответствие строки с заданным шаблоном
|
||||
- `contains(str)` - проверяет, содержится ли в строке подстрока str
|
||||
- `equalsIgnoreCase(str)` - проверяет, равны ли строки вне зависимости от регистра (tEsT = TEST)
|
||||
- `isEmpty()` - возвращает true, если строка пустая
|
||||
|
||||
Кроме того, доступны автоматические функции-расширения, если функция принимает в качестве первого аргумента строку:
|
||||
|
||||
@[code](../../code/basics/string_functions1.own)
|
12
docs/docs/ru/basics/strings.md
Normal file
12
docs/docs/ru/basics/strings.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Строки
|
||||
|
||||
Строки задаются в двойных кавычках и могут быть многострочные. Поддерживается юникод и экранирование символов:
|
||||
|
||||
```own
|
||||
str = "\n\tЭто
|
||||
\tмногострочный
|
||||
\tтекст
|
||||
"
|
||||
```
|
||||
|
||||
Для вывода строк есть два оператора `print` и `println`
|
24
docs/docs/ru/basics/types.md
Normal file
24
docs/docs/ru/basics/types.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Типы
|
||||
|
||||
В OwnLang есть такие типы:
|
||||
|
||||
* Number - числа (охватывает как целые, так и вещественные числа)
|
||||
* String - строки
|
||||
* Array - массивы
|
||||
* Map - объекты (ассоциативные массивы)
|
||||
* Function - функции
|
||||
|
||||
Поскольку OwnLang - динамически типизируемый язык программирования, это значит, что явно объявлять типы не нужно.
|
||||
|
||||
```own
|
||||
x = 10 // целое число
|
||||
y = 1.61803 // вещественное число
|
||||
z = "abcd" // строка
|
||||
```
|
||||
|
||||
Если какая-либо функция предполагает использование строк в качестве аргументов, а были переданы числа, то значения автоматически приведутся к строке.
|
||||
|
||||
```own
|
||||
x = 90
|
||||
print x
|
||||
```
|
13
docs/docs/ru/links.md
Normal file
13
docs/docs/ru/links.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Ссылки
|
||||
|
||||
## Загрузки
|
||||
|
||||
Android: [Free](https://play.google.com/store/apps/details?id=com.annimon.ownlang.free) / [Pro](https://play.google.com/store/apps/details?id=com.annimon.ownlang)
|
||||
PC / плагин Netbeans / прочее: [GitHub Releases](https://github.com/aNNiMON/Own-Programming-Language-Tutorial/releases)
|
||||
Исходный код: [GitHub](https://github.com/aNNiMON/Own-Programming-Language-Tutorial)
|
||||
|
||||
Также доступно в виде пакета в AUR:
|
||||
|
||||
```
|
||||
paru -S ownlang
|
||||
```
|
20
docs/package.json
Normal file
20
docs/package.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "ownlang-docs",
|
||||
"version": "1.0.0",
|
||||
"description": "OwnLang Documentation",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"docs:dev": "vuepress dev docs",
|
||||
"docs:build": "vuepress build docs"
|
||||
},
|
||||
"keywords": ["documentation", "ownlang", "programming-language"],
|
||||
"author": "aNNiMON",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"prismjs": "^1.29.0",
|
||||
"@vuepress/client": "2.0.0-beta.68",
|
||||
"@vuepress/plugin-prismjs": "2.0.0-beta.68",
|
||||
"vue": "^3.3.8",
|
||||
"vuepress": "2.0.0-beta.68"
|
||||
}
|
||||
}
|
1780
docs/pnpm-lock.yaml
Normal file
1780
docs/pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user