Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
387a80c
Add multi-project structure
aNNiMON Aug 26, 2023
6dcce50
Move classes to separate modules
aNNiMON Aug 26, 2023
0ddf720
Use separate dependency versions declaration
aNNiMON Aug 27, 2023
2c734d1
Configure run tasks
aNNiMON Aug 27, 2023
02e340a
Fix canvasfx module with Java FX 17
aNNiMON Aug 28, 2023
d6e9751
Switch to Java11+ features where possible
aNNiMON Aug 28, 2023
3fc2d41
Mark core as compileOnlyApi in module dependencies
aNNiMON Aug 30, 2023
da7718a
Add JMH benchmark for programs
aNNiMON Aug 30, 2023
9f58b82
Define functions and constants in root scope
aNNiMON Sep 3, 2023
bf5e156
Use new switch and pattern matching, fix deprecations
aNNiMON Sep 3, 2023
179b590
Switch to ScopeHandler in modules
aNNiMON Sep 4, 2023
24d3500
Deprecate old Variables/Functions methods
aNNiMON Sep 4, 2023
e6482af
Fix scope of foreach and match statements
aNNiMON Sep 7, 2023
de66577
Change list pattern matcher behavior for single element
aNNiMON Sep 7, 2023
1718799
Fix url in image examples
aNNiMON Sep 7, 2023
61b3c82
Simplify use statement to take variable WORD only arguments
aNNiMON Sep 9, 2023
18b62d9
Fix use statement in programs
aNNiMON Sep 9, 2023
476b55b
Separate constants and functions in module, don't load it twice
aNNiMON Sep 9, 2023
74b2b55
Fix concurrent modification exception in ounit, when new modules are …
aNNiMON Sep 9, 2023
0b0e435
Add columns in position information
aNNiMON Sep 9, 2023
d32b650
Fix incorrect token positions in lexer
aNNiMON Sep 11, 2023
9e75f42
Use immutable map, fast skip whitespaces in lexer
aNNiMON Sep 11, 2023
18519f5
More strict lexer, fixed HEX numbers and quote escaping
aNNiMON Sep 16, 2023
cdcc367
Added floating number scientific notation
aNNiMON Sep 16, 2023
5f23bd6
Use local variable for frequently used fields in Lexer
aNNiMON Sep 16, 2023
af635cd
Better explaining parse errors
aNNiMON Sep 16, 2023
12464a3
Use ranges in parser
aNNiMON Sep 17, 2023
919b54b
Add base type for exceptions
aNNiMON Sep 17, 2023
f2f23c8
Constants access priority
aNNiMON Sep 17, 2023
e565952
Introduce DECIMAL_NUMBER token, fix HEX numbers with 'E' incorrectly …
aNNiMON Sep 17, 2023
59a12db
More informative parser errors with ranges, removed LexerException
aNNiMON Sep 27, 2023
f151df2
Introduce stages for each main feature
aNNiMON Sep 30, 2023
1335fce
Add parse errors formatter
aNNiMON Sep 30, 2023
889cd67
Show linter results after validation
aNNiMON Oct 1, 2023
589c53f
Add listing constants to REPL
aNNiMON Oct 1, 2023
a431828
Use stages in programs test
aNNiMON Oct 1, 2023
e43d04d
Move optimization logic to OptimizationStage class, don't print summary
aNNiMON Oct 2, 2023
46d2c11
Fix optimization in use statement and match expression with _ matcher
aNNiMON Oct 2, 2023
4635e09
Fix dead code elimination optimization removes assignment on shadowin…
aNNiMON Oct 2, 2023
718034b
Run tests with maximum optimization
aNNiMON Oct 2, 2023
89279b9
Call stack memory optimization
aNNiMON Oct 2, 2023
b7ed442
Simplify variables grabber
aNNiMON Oct 2, 2023
470f1db
Fix function call statement passes Variable expression instead of fun…
aNNiMON Oct 3, 2023
979b370
[files] Detailed error message for fopen
aNNiMON Oct 3, 2023
73051a0
Show function call position in call stack
aNNiMON Oct 4, 2023
e1eae28
Generalized way to show source located errors (parse and runtime errors)
aNNiMON Oct 4, 2023
4dbd80f
Limit call stack function output length
aNNiMON Oct 4, 2023
65bba00
Call stack for class constructor
aNNiMON Oct 4, 2023
54a2d24
Source location for unknown class/function exceptions
aNNiMON Oct 4, 2023
2a65058
Formatted error output in program tests
aNNiMON Oct 4, 2023
048f9c1
Remove unused methods in Scopes
aNNiMON Oct 4, 2023
b01ccf7
Add input sources and source loading stage
aNNiMON Oct 5, 2023
fb2af23
Add Beautifier as a stage
aNNiMON Oct 5, 2023
ec6899f
[functional] Add Stream.filterNot
aNNiMON Oct 5, 2023
2b9243e
[functional] Unify functional operators
aNNiMON Oct 5, 2023
449115d
[functional] Deny varargs input argument for stream
aNNiMON Oct 5, 2023
2ac9364
[functional] Move indexed variant of Stream.forEach to Stream,forEach…
aNNiMON Oct 5, 2023
6bbac8d
Source located function, class and arguments
aNNiMON Oct 5, 2023
c0580a5
Replace RuntimeException with OwnLangRuntimeException in modules
aNNiMON Oct 5, 2023
c3b0c6f
Show location of the closest error from call stack
aNNiMON Oct 6, 2023
411385e
Better container access formatting
aNNiMON Oct 6, 2023
5fae336
Add syntax schema for Intellij Idea
aNNiMON Oct 13, 2023
0a98cb5
[java] Add Boolean converter to Value, add collections example
aNNiMON Oct 13, 2023
1858dd5
Parse error highlighting for include statement
aNNiMON Oct 14, 2023
c6c3f26
Remove unnecessary abstraction Expression, use Statement only as marker
aNNiMON Oct 14, 2023
963700d
Add semantic linter as a required stage
aNNiMON Oct 15, 2023
bb4dfe1
Source located error in linter for include statement
aNNiMON Oct 15, 2023
66ac44e
Source located VariableDoesNotExistsException
aNNiMON Oct 15, 2023
dc9098c
Don't include canvasfx module to desktop app by default
aNNiMON Oct 15, 2023
be5e639
Move classes implementation outside of parser module
aNNiMON Oct 23, 2023
91f1bdf
Add lint validation for break/continue statement outside the loop body
aNNiMON Oct 24, 2023
105b7f9
Fix visitors skip class declaration
aNNiMON Oct 24, 2023
02c83bc
[functional] Add groupby and Stream.groupBy
aNNiMON Oct 25, 2023
f016c26
[std] Add parseDouble, nanotime, exit, getenv, getprop
aNNiMON Oct 28, 2023
b779ebb
Convert OwnLang value to Java object
aNNiMON Nov 9, 2023
1b856d2
[server] Add server module
aNNiMON Nov 9, 2023
3642b33
[server] More server functions
aNNiMON Nov 10, 2023
3cb3a03
Add Prism.js and highlight.js syntax highlight definitions
aNNiMON Nov 15, 2023
ee4148d
Add VuePress documentation subproject
aNNiMON Nov 15, 2023
0adfe4d
Split modules.yml documentation per module
aNNiMON Nov 16, 2023
63c4445
Add modules documentation generator
aNNiMON Nov 19, 2023
4ad5638
Update README
aNNiMON Nov 20, 2023
4ea760a
Adjust docs styles
aNNiMON Nov 23, 2023
ca780e5
Add custom components, update vuepress version
aNNiMON Nov 23, 2023
54f0c05
Add Gradle ownlangExec and generateMarkdownModules tasks
aNNiMON Nov 25, 2023
056359c
Preserve the order of Map elements by default
aNNiMON Nov 27, 2023
8d2d9bb
Rearrange module pages
aNNiMON Nov 27, 2023
b6c03d0
Collapse long Constants block by default
aNNiMON Nov 27, 2023
c02185d
Add new functions documentation
aNNiMON Nov 27, 2023
d1b3f90
Add collections documentation
aNNiMON Dec 8, 2023
f8f15c4
Add server documentation
aNNiMON Dec 8, 2023
1563a00
[server] Add Header constants
aNNiMON Dec 10, 2023
c18060a
Move ModulesInfoCreator to docs module
aNNiMON Dec 10, 2023
4358286
[okhttp] Add docs
aNNiMON Dec 10, 2023
0df343e
Improve docs generators
aNNiMON Dec 11, 2023
acc9a3a
Small fixes
aNNiMON Dec 11, 2023
679a1e3
[http] Add synchronous httpSync
aNNiMON Dec 11, 2023
7800913
Add gradle task for running npm
aNNiMON Dec 13, 2023
c7c218a
Redeclare module versions
aNNiMON Dec 15, 2023
67ebe37
Add changelog page
aNNiMON Dec 15, 2023
6a83339
[server] Add more methods to ContextValue
aNNiMON Dec 18, 2023
0d70c3e
Add server examples
aNNiMON Dec 30, 2023
fbc9a0d
[functional] Add tomap, Stream::toMap, Stream::anyMatch, Stream::allM…
aNNiMON Jan 1, 2024
ce2f166
Add changelog in docs
aNNiMON Jan 10, 2024
3ba96aa
Add search plugin, build docs task
aNNiMON Jan 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 2 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
/.gradle/
/.idea/
/.nb-gradle/
/build/
**/build/
/dist/
/out/
/store/
/optimizations/
/nbproject/private/
/src/main/generatedJava/
OwnLang.iml
.nb-gradle-properties
OwnLang.iml
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ OwnLang - dynamic functional programming language inspired by Scala and Python.

| Free | Pro | Desktop |
| :--: | :-: | :-----: |
| [![Free](https://developer.android.com/images/brand/en_generic_rgb_wo_45.png)](https://play.google.com/store/apps/details?id=com.annimon.ownlang.free) | [![Pro](https://developer.android.com/images/brand/en_generic_rgb_wo_45.png)](https://play.google.com/store/apps/details?id=com.annimon.ownlang) | [v1.5.0](https://github.com/aNNiMON/Own-Programming-Language-Tutorial/releases/tag/v1.5.0)
| [![Free](https://developer.android.com/images/brand/en_generic_rgb_wo_45.png)](https://play.google.com/store/apps/details?id=com.annimon.ownlang.free) | [![Pro](https://developer.android.com/images/brand/en_generic_rgb_wo_45.png)](https://play.google.com/store/apps/details?id=com.annimon.ownlang) | [v1.5.0](https://github.com/aNNiMON/Own-Programming-Language-Tutorial/releases/tag/v1.5.0) |

Also available as AUR package:

Expand Down Expand Up @@ -71,7 +71,7 @@ fizzbuzz()
Operate data in functional style.

```scala
use ["std", "functional"]
use std, functional

nums = [1,2,3,4,5,6,7,8,9,10]
nums = filter(nums, def(x) = x % 2 == 0)
Expand All @@ -93,7 +93,7 @@ println "Sum: " + stream(range(1, 11))
Why not?

```scala
use ["std", "types", "math"]
use std, types, math

def `..`(a, b) = range(a, b)
def `**`(a, b) = int(pow(a, b))
Expand All @@ -107,13 +107,11 @@ for y : 1 .. 10 {
Easy async HTTP requests with `http` module.

```scala
use "std"
use "http"
use "functional"
use std, http, functional

// GET request
http("https://api.github.com/events", def(r) {
use "json"
use json
events = jsondecode(r)
println events[0]
})
Expand Down Expand Up @@ -141,7 +139,7 @@ def patch_callback(v) {

## Build

Build using Gradle `./gradlew dist`
Build using Gradle `./gradlew shadowJar`

or take a look to [latest release](https://github.com/aNNiMON/Own-Programming-Language-Tutorial/releases/latest) for binaries.

Expand Down
92 changes: 28 additions & 64 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,70 +1,34 @@
plugins {
id 'java'
ext {
versions = [
project: '2.0.0',

json: '20230227', // org.json:json
snakeyaml: '1.20', // org.yaml:snakeyaml
okhttp: '3.8.1', // com.squareup.okhttp3:okhttp
socket: '1.0.2', // io.socket:socket.io-client
jline: '2.14.5', // jline:jline

javalin: '5.6.3', // io.javalin:javalin
slf4j: '2.0.9', // org.slf4j:slf4j-simple
jackson: '2.15.3', // com.fasterxml.jackson.core:jackson-databind

junit: '5.9.2', // org.junit:junit-bom
jmh: '1.37', // org.openjdk.jmh:jmh-core
assertj: '3.24.2' // org.assertj:assertj-core
]
}

group = 'com.annimon'
version = '2.0-SNAPSHOT'

[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
if (!hasProperty('mainClass')) {
ext.mainClass = 'com.annimon.ownlang.Main'
}

ext.generatedJavaDir = "${rootProject.projectDir}/src/main/generatedJava"
sourceSets.main.java.srcDirs += project.generatedJavaDir

repositories {
mavenCentral()
}

tasks.register('generateJavaSources') {
doLast {
def source = """
package com.annimon.ownlang;
class Gen {
private Gen() {}
public static final String BUILD_DATE = "${new Date().format('YYMMdd')}";
}
""".stripIndent()
def genFile = new File("${project.generatedJavaDir}/com/annimon/ownlang/Gen.java")
genFile.getParentFile().mkdirs()
genFile.write(source)
allprojects {
repositories {
mavenCentral()
}
}
compileJava.dependsOn(generateJavaSources)

tasks.register('run', JavaExec) {
dependsOn classes
mainClass = project.mainClass
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
ignoreExitValue true
}

tasks.register('runOptimizing', JavaExec) {
dependsOn classes
mainClass = project.mainClass
classpath = sourceSets.main.runtimeClasspath
ignoreExitValue true
args '-o 9 -m -a -f program.own'.split(' ')
}


dependencies {
implementation ('io.socket:socket.io-client:1.0.2') {
exclude group: 'org.json', module: 'json'
gradle.projectsEvaluated {
tasks.withType(JavaCompile).tap {
configureEach {
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
}
}
implementation 'org.json:json:20230227'
implementation 'org.yaml:snakeyaml:1.20'
implementation 'jline:jline:2.14.5'

testImplementation platform('org.junit:junit-bom:5.9.2')
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.2'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.openjdk.jmh:jmh-core:1.37'
testImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.37'
}

test {
useJUnitPlatform()
}
6 changes: 6 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
.temp
.cache
docs/.vuepress/configs/modules.js
docs/.vuepress/dist/
docs/*/modules/
54 changes: 54 additions & 0 deletions docs/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
plugins {
id 'java'
}

group = 'com.annimon'
version = versions.project

dependencies {
implementation project(":ownlang-core")
implementation project(":ownlang-parser")
implementation project(":ownlang-utils")
implementation project(":modules:main")
implementation project(":modules:canvasfx")
implementation project(":modules:server")

implementation "org.yaml:snakeyaml:${versions.snakeyaml}"
}

tasks.register('generateMarkdownModules') {
group = "documentation"
def ownlangExec = tasks.getByPath(':ownlang-desktop:ownlangExec')
doFirst {
ownlangExec.configure {
workingDir '../docs/src'
args '-f', 'docgen-md.own'
}
}
finalizedBy ownlangExec
}

tasks.register('runDocsDev', Exec) {
group = "documentation"
description = "Start docs dev server"
dependsOn generateMarkdownModules
workingDir '../docs/docs'
commandLine 'pnpm', 'docs:dev'
}

tasks.register('buildDocs', Exec) {
group = "documentation"
description = "Build docs to static site"
dependsOn generateMarkdownModules
workingDir '../docs/docs'
commandLine 'pnpm', 'docs:build'
}

tasks.register('generateModuleInfo', JavaExec) {
group = "documentation"
description = "Run sample program"
dependsOn classes
mainClass = 'com.annimon.ownlang.docs.ModulesInfoCreator'
classpath = sourceSets.main.runtimeClasspath
args 'server', 'okhttp'
}
30 changes: 30 additions & 0 deletions docs/docs/.vuepress/components/Scope.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<template>
<span
class="badge scope"
:class="scope"
>
<slot>{{ scope }}</slot>
</span>
</template>

<script setup>
defineProps({
scope: {
type: String,
required: true
}
})
</script>

<style scoped>
.badge.scope {
vertical-align: middle;
text-transform: capitalize;
}
.badge.android {
background-color: var(--c-badge-tip);
}
.badge.desktop {
background-color: var(--usc-scope);
}
</style>
32 changes: 32 additions & 0 deletions docs/docs/.vuepress/components/Since.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<span class="since">{{ text }} <b>{{ version }}</b></span>
</template>

<script>
export default {
props: {
text: {
type: String,
required: false,
default: ''
},
version: {
type: String,
required: true
}
}
}
</script>

<style scoped>
.since {
display: inline-block;
font-size: 13px;
height: 18px;
line-height: 18px;
border-radius: 3px;
padding: 0 4px;
color: var(--c-bg);
background-color: var(--usc-since);
}
</style>
63 changes: 63 additions & 0 deletions docs/docs/.vuepress/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { defineUserConfig, defaultTheme } from 'vuepress'
import { getDirname, path } from '@vuepress/utils'
import { registerComponentsPlugin } from '@vuepress/plugin-register-components'
import { prismjsPlugin } from '@vuepress/plugin-prismjs'
import { searchPlugin } from '@vuepress/plugin-search'
import { sidebarConfig } from './configs/sidebar'
import { navbarConfig } from './configs/navbar'
import Prism from 'prismjs';
import definePrismOwnLang from '../../../editors/prismjs/own-language.js'

definePrismOwnLang(Prism)
const __dirname = getDirname(import.meta.url)

export default defineUserConfig({
base: "/docs/ownlang/",
locales: {
'/en/': {
lang: 'en-US',
title: 'OwnLang',
description: 'OwnLang documentation',
},
'/ru/': {
lang: 'ru-RU',
title: 'OwnLang',
description: 'Документация OwnLang',
}
},

theme: defaultTheme({
repo: 'aNNiMON/Own-Programming-Language-Tutorial',
docsBranch: 'next',
editLinkPattern: ':repo/blob/:branch/docs/docs/:path',
editLinkText: 'View source',
contributors: false,
locales: {
'/en/': {
selectLanguageName: 'English',
sidebar: sidebarConfig.en,
navbar: navbarConfig.en
},
'/ru/': {
selectLanguageName: 'Русский',
sidebar: sidebarConfig.ru,
navbar: navbarConfig.ru
}
}
}),

plugins: [
prismjsPlugin({
preloadLanguages: ['own', 'json']
}),
registerComponentsPlugin({
componentsDir: path.resolve(__dirname, './components'),
}),
searchPlugin({
locales: {
'/en/': { placeholder: 'Search' },
'/ru/': { placeholder: 'Поиск' },
},
}),
],
})
16 changes: 16 additions & 0 deletions docs/docs/.vuepress/configs/navbar.js
Original file line number Diff line number Diff line change
@@ -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
Loading