Add VuePress documentation subproject

This commit is contained in:
aNNiMON 2023-11-15 21:53:21 +02:00 committed by Victor Melnik
parent bd836c868a
commit 2a45a30778
53 changed files with 2933 additions and 0 deletions

4
docs/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
node_modules
.temp
.cache
/docs/*/modules/

View 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']
}),
],
})

View 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

View 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: [
]
}
}

View 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
View 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
---

View File

@ -0,0 +1,5 @@
arr = ["a", "b", "c"]
extract(var1, var2, var3) = arr
print var1 // a
print var2 // b
print var3 // c

View File

@ -0,0 +1,4 @@
arr = ["a", "b", "c"]
var1 = arr[0]
var2 = arr[1]
var3 = arr[2]

View File

@ -0,0 +1,4 @@
map = {"key1": 1, "test", "text"}
extract(var1, var2) = map
println var1 // [key1, 1]
println var2 // [test, text]

View File

@ -0,0 +1,3 @@
extract(x, , z) = [93, 58, 90]
println x // 93
println z // 90

View 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

View 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
}

View File

@ -0,0 +1,7 @@
x = 2
print match x {
case 1: "One"
case 2: "Two"
case "str": "String"
case _: "Unknown"
}

View File

@ -0,0 +1,9 @@
x = "str"
match x {
case "": {
println "Empty string"
}
case "str": {
println "String!"
}
}

View 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

View 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 .. +∞)

View 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, []]]]]]]]

View 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
}
}

View 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()

View 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)

View 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)

View 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)
}

View 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)
}

View 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
}

View 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
}

View 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)
}

View 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
View 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)

View 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)

View 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

View File

@ -0,0 +1,9 @@
# Comments
```own
// Line comment
/* multiline
comment
*/
print /*inner comment*/ "Text"
```

View 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)

View 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)

View 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)

View 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)

View 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)

View 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.

View 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
View 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
View 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)

View 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)

View File

@ -0,0 +1,8 @@
# Функции массивов
Поля:
- `length` - количество элементов массива
Функции:
- `isEmpty()` - возвращает true, если массив пуст
- `joinToString(delimiter = "", prefix = "", suffix = "")` - склеивает массив в строку

View File

@ -0,0 +1,9 @@
# Комментарии
```own
// Однострочный комментарий
/* многострочный
комментарий
*/
print /*или так*/ "Текст"
```

View 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)

View 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)

View 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)

View 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)

View 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)

View File

@ -0,0 +1,12 @@
# Строки
Строки задаются в двойных кавычках и могут быть многострочные. Поддерживается юникод и экранирование символов:
```own
str = "\n\tЭто
\tмногострочный
\tтекст
"
```
Для вывода строк есть два оператора `print` и `println`

View 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
View 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
View 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

File diff suppressed because it is too large Load Diff