51 Commits
test ... master

Author SHA1 Message Date
4791aefd76 change argon version 2025-02-19 02:44:02 +00:00
8f51b24c7c fix brainfuck, allow multiplying array by int, and fix incorrect error message in ord 2025-02-19 02:31:32 +00:00
c75be1c8ed fix mod order 2024-12-04 12:51:03 +00:00
885a5b0387 add platform object 2024-10-19 03:02:16 +01:00
60cbda6d9d add new input types and fix input bug that only shows up on windows (how predictable) 2024-10-15 22:52:27 +01:00
5eb2a0e789 add input history 2024-10-15 19:18:42 +01:00
55db84fcce make it so its possible to negate a functions value without needing brackets 2024-10-08 15:13:58 +01:00
4910a2337b fix flashing text in terminal 2024-10-08 09:43:26 +01:00
William Bell
f98cf47988 Update readme.md to have installer script 2024-08-21 11:51:42 +01:00
3761070e82 remove typo 2024-05-30 17:03:47 +01:00
7aadb812e4 fix delete keyword not doing anything when deleting a variable, and move length calculation to only when needed 2024-05-30 17:03:29 +01:00
5afa0b10c7 make brackets more efficient 2024-05-30 13:08:10 +01:00
9945e1590f add join 2024-05-30 12:49:29 +01:00
d48b0ab7b6 add eval and potentially speed up variable access speeds when multi threading. fix bug in threading count 2024-05-30 12:46:25 +01:00
051581c84b add copy and move functions 2024-05-30 00:25:16 +01:00
677643eeed remove debug 2024-05-29 23:57:48 +01:00
f0876bd5ac fix being able to run a script in a parent folder from a child folder 2024-05-29 23:15:49 +01:00
37a3d56b5f fix broken import logic 2024-04-12 17:08:55 +01:00
0a8952bc3b Update version number to 3.0.5 and fix code inconsistency 2024-04-12 16:14:46 +01:00
a8fb5d4c1f fix up inconsistent error types 2024-04-09 19:22:43 +01:00
42e12933bf fix bug which would make syntax errors inside functions display the wrong line 2024-04-09 16:19:29 +01:00
31158dfb89 add support for version numbers and change version 2024-04-06 15:53:05 +01:00
e8d25d231c get rid of circular imports 2024-04-06 15:48:00 +01:00
bf15b435c2 fix json parse not throwing error when incorrect 2024-04-05 19:41:42 +02:00
William Bell
82aae37479 Update readme.md 2024-04-05 09:16:46 +02:00
269430b025 fix trig inaccurate when given a large input 2024-03-14 12:51:51 +00:00
23a9a443d6 add byte object 2024-03-09 15:11:56 +00:00
fafc016ea5 remove isotope files 2024-03-04 23:22:52 +00:00
a57d79587e increment version 2024-03-04 22:03:14 +00:00
046ad89679 fix main being the wrong variable 2024-03-04 10:50:58 +00:00
cf040a5209 fix comments being broken for isLine level 3 2024-03-04 00:00:34 +00:00
efcc155e55 fix no exit function 2024-03-03 23:06:10 +00:00
56f5fbd61a fix while loop having isLine param of 2 instead of 3 2024-02-23 23:50:44 +00:00
William Bell
7a7f785b64 Merge pull request #3 from Open-Argon/master
parse imports with fixed paths before running all the code
2024-02-23 21:54:01 +00:00
b3a07d7f63 parse imports with fixed paths before running all the code 2024-02-23 21:50:53 +00:00
7f86d345ae store known failures which are not necessarily errors 2023-11-23 14:01:09 +00:00
4b66d23597 add get_value and fix map function 2023-11-17 11:35:05 +00:00
c207c0668d Fix indentation and translation errors in doWrap,
forLoop, ifStatement, and whileLoop functions.
Also fix syntax error in broken_funcCall test
file.
2023-11-14 21:48:04 +00:00
65c608e088 allow single line if statements 2023-11-14 20:27:17 +00:00
8e887aeaff allow single line try catch 2023-11-14 20:24:04 +00:00
6dee9d6874 oops, accidently left some debugging code in 2023-11-14 20:21:58 +00:00
6295e23d1b add paster to some weird golang incorrect memory address bug 2023-11-14 20:19:24 +00:00
140ce3d2a8 fix thread count 2023-08-12 01:01:47 +01:00
501bbff1a2 fix do not working if not after space in shell 2023-08-10 12:05:04 +01:00
541ff1b172 change 2023-08-08 23:28:30 +01:00
b93ecdc4d7 add status badge 2023-08-08 23:10:14 +01:00
8d62e4c0c1 try fix 2023-08-08 23:07:05 +01:00
3f2c7d8f5b try new release 2023-08-08 23:00:33 +01:00
820da24175 remove release 2023-08-08 22:33:15 +01:00
41b716c690 fix 2023-08-08 21:18:22 +01:00
2a801a19d8 fix release 2023-08-08 21:16:49 +01:00
55 changed files with 1203 additions and 760 deletions

24
.github/workflows/build_release.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
# workflow name
name: Generate release-artifacts
on:
release:
types:
- created
# workflow tasks
jobs:
generate:
name: Generate cross-platform builds
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Generate build files
uses: thatisuday/go-cross-build@v1
with:
platforms: 'linux/amd64, darwin/amd64, windows/amd64'
package: 'src'
name: 'argon'
compress: 'true'
dest: 'bin'

View File

@@ -1,45 +0,0 @@
name: Build and Release Go Binary
on:
release:
types:
- created
jobs:
build:
name: Build and Release
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.20 # Use your desired Go version
- name: Build Go project
run: go build -o argon ./src
- name: Create release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false
- name: Upload binary to release
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./argon
asset_name: argon
asset_content_type: application/octet-stream

View File

@@ -1,4 +0,0 @@
{
"name": "argon-v3",
"version": "3.0.1"
}

View File

@@ -1,2 +1,2 @@
@echo off @echo off
go build -trimpath -ldflags="-s -w" -o bin/argon.exe ./src go build -trimpath -ldflags="-s -w" -tags WINDOWS -o bin/argon.exe ./src

View File

@@ -3,4 +3,4 @@
:: run the go run command passing the path to the main.go file, with the working directory set to the bin folder. pass in the arguments :: run the go run command passing the path to the main.go file, with the working directory set to the bin folder. pass in the arguments
set __ARGON_DEBUG__=true set __ARGON_DEBUG__=true
go run ./src %* go run -tags WINDOWS ./src %*

12
go.mod
View File

@@ -7,7 +7,15 @@ require (
github.com/wadey/go-rounding v1.1.0 github.com/wadey/go-rounding v1.1.0
) )
require github.com/joho/godotenv v1.5.1 // indirect require (
github.com/chzyer/readline v1.5.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/shirou/gopsutil v2.21.11+incompatible // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
)
require ( require (
github.com/gabriel-vasile/mimetype v1.4.2 github.com/gabriel-vasile/mimetype v1.4.2
@@ -18,7 +26,7 @@ require (
github.com/jwalton/go-supportscolor v1.1.0 github.com/jwalton/go-supportscolor v1.1.0
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.17 // indirect
golang.org/x/sys v0.6.0 // indirect golang.org/x/sys v0.19.0 // indirect
golang.org/x/term v0.6.0 golang.org/x/term v0.6.0
golang.org/x/text v0.8.0 golang.org/x/text v0.8.0
) )

18
go.sum
View File

@@ -1,7 +1,13 @@
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jwalton/go-supportscolor v1.1.0 h1:HsXFJdMPjRUAx8cIW6g30hVSFYaxh9yRQwEWgkAR7lQ= github.com/jwalton/go-supportscolor v1.1.0 h1:HsXFJdMPjRUAx8cIW6g30hVSFYaxh9yRQwEWgkAR7lQ=
@@ -11,19 +17,31 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/shirou/gopsutil v2.21.11+incompatible h1:lOGOyCG67a5dv2hq5Z1BLDUqqKp3HkbjPcz5j6XMS0U=
github.com/shirou/gopsutil v2.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
github.com/wadey/go-rounding v1.1.0 h1:RAs9dMkB/uUHFv9ljlbRFC8/kBrQ5jhwt1GQq+2cciY= github.com/wadey/go-rounding v1.1.0 h1:RAs9dMkB/uUHFv9ljlbRFC8/kBrQ5jhwt1GQq+2cciY=
github.com/wadey/go-rounding v1.1.0/go.mod h1:/uD953tCL6Fea2Yp+LZBBp8d60QSObkMJxY6SPOJ5QE= github.com/wadey/go-rounding v1.1.0/go.mod h1:/uD953tCL6Fea2Yp+LZBBp8d60QSObkMJxY6SPOJ5QE=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=

View File

@@ -1 +0,0 @@
[{"Name":"welcome","Version":"1.0.0","URL":"http://isotope.wbell.dev/isotope-download?name=welcome\u0026version=1.0.0","Remote":"isotope.wbell.dev"},{"Name":"this","Version":"1.0.0","URL":"http://isotope.wbell.dev/isotope-download?name=this\u0026version=1.0.0","Remote":"isotope.wbell.dev"},{"Name":"csv.ar","Version":"1.0.0","URL":"http://isotope.wbell.dev/isotope-download?name=csv.ar\u0026version=1.0.0","Remote":"isotope.wbell.dev"}]

View File

@@ -5,7 +5,9 @@
<h1>Argon v3</h1> <h1>Argon v3</h1>
</div> </div>
ARGON 3 is a math-driven programming language designed to make code easy to read and write. It's not meant to be fast, as it's interpreted. This specification should be used as a guideline, and is subject to change for later versions. Later updates for Argon 3 should be backwards compatible (where possible) with code designed for older versions of the interpreter. [![Go](https://github.com/Open-Argon/argon-v3/actions/workflows/go.yml/badge.svg)](https://github.com/Open-Argon/argon-v3/actions/workflows/go.yml)
ARGON 3 is a math-driven programming language designed to make code easy to read and write. It's not meant to be fast, as it's interpreted.
## 📚 Features ## 📚 Features
- Easy to read and write: Argon 3 is designed with clarity of code in mind, making it easier for you and others to read and write code. - Easy to read and write: Argon 3 is designed with clarity of code in mind, making it easier for you and others to read and write code.
@@ -13,10 +15,14 @@ ARGON 3 is a math-driven programming language designed to make code easy to read
- Math-driven: Designed for mathematical computations, Argon 3 uses techniques and rules set in maths. It's designed to be easy for mathematicians to write and understand algorithms in. - Math-driven: Designed for mathematical computations, Argon 3 uses techniques and rules set in maths. It's designed to be easy for mathematicians to write and understand algorithms in.
- Interpreted: Argon 3 is an interpreted language, so you don't need to compile your code before running it. - Interpreted: Argon 3 is an interpreted language, so you don't need to compile your code before running it.
- Cross-platform: Argon 3 can be run on any platform that has an interpreter for it. - Cross-platform: Argon 3 can be run on any platform that has an interpreter for it.
- Lightweight: The Argon 3 interpreter is small and doesn't require a lot of system resources to run.
## 💻 Installation ## 💻 Installation
As of now, Argon 3 does not have an installer. Feel free to clone this repo and run the `build` file for your plateform. the build will be found in `bin/argon(.exe)`. ### Windows
As of now, Argon 3 does not have a windows installer. Feel free to clone this repo and run the `build.bat` file. the build will be found in `bin\argon.exe`.
If you want to also use the isotope package manager, you can find the source code [here](https://github.com/open-argon/isotope).
### UNIX based (macOS and Linux)
Unix based operating systems can use the argon installer script found at [https://argon.wbell.dev/](https://argon.wbell.dev/). The script should run on all modern linux distros, and should also work on macOS with limited support. It may also work on other Unix based operating systems such at FreeBSD, but those are untested but are supported if you have issues.
## 📖 Usage ## 📖 Usage
To use Argon 3, you can create a file with the .ar extension and write your code in it. Then, you can run your code using the interpreter. For example, if you have a file called example.ar, you can run it using the following command: To use Argon 3, you can create a file with the .ar extension and write your code in it. Then, you can run your code using the interpreter. For example, if you have a file called example.ar, you can run it using the following command:

9
server_test/app.ar Normal file
View File

@@ -0,0 +1,9 @@
import "http.ar" as http
let server = http.server()
let home(req,res) = do
res.send("hello world")
server.get("/", home)
server.run()

View File

@@ -23,7 +23,6 @@ func ArArray(arr []any) ArObject {
anymap{ anymap{
"__name__": "array", "__name__": "array",
"__value__": arr, "__value__": arr,
"length": newNumber().SetUint64(uint64(len(arr))),
}, },
} }
val.obj["__setindex__"] = builtinFunc{ val.obj["__setindex__"] = builtinFunc{
@@ -62,15 +61,48 @@ func ArArray(arr []any) ArObject {
return nil, ArErr{} return nil, ArErr{}
}, },
} }
val.obj["__Multiply__"] = builtinFunc{
"__Multiply__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"Type Error", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "number" {
return nil, ArErr{"Type Error", "cannot multiply array by " + typeof(a[0]), 0, "", "", true}
}
n := a[0].(number)
if !n.IsInt() {
return nil, ArErr{"Value Error", "cannot multiply array by float", 0, "", "", true}
}
if n.Sign() < 0 {
return nil, ArErr{"Value Error", "cannot multiply array by negative number", 0, "", "", true}
}
size := int(n.Num().Int64())
retval := make([]any, 0, len(arr)*size)
for i := 0; i < size; i++ {
retval = append(retval, arr...)
}
return ArArray(retval), ArErr{}
}}
val.obj["__getindex__"] = builtinFunc{ val.obj["__getindex__"] = builtinFunc{
"__getindex__", "__getindex__",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
// a[0] is start // a[0] is start
// a[1] is end // a[1] is end
// a[2] is step // a[2] is step
if len(a) > 3 { if len(a) > 3 || len(a) == 0 {
return nil, ArErr{"Type Error", "expected 1 to 3 arguments, got " + fmt.Sprint(len(a)), 0, "", "", true} return nil, ArErr{"Type Error", "expected 1 to 3 arguments, got " + fmt.Sprint(len(a)), 0, "", "", true}
} }
{
if len(a) == 1 {
if typeof(a[0]) == "string" {
var name = ArValidToAny(a[0]).(string)
if name == "length" {
return newNumber().SetInt64(int64(len(arr))), ArErr{}
}
}
}
}
var ( var (
start int = 0 start int = 0
end any = nil end any = nil
@@ -183,7 +215,6 @@ func ArArray(arr []any) ArObject {
} }
} }
arr = append(arr[:num], arr[num+1:]...) arr = append(arr[:num], arr[num+1:]...)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr val.obj["__value__"] = arr
return nil, ArErr{} return nil, ArErr{}
}} }}
@@ -198,7 +229,6 @@ func ArArray(arr []any) ArObject {
} }
} }
arr = append(arr, args...) arr = append(arr, args...)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr val.obj["__value__"] = arr
return nil, ArErr{} return nil, ArErr{}
}, },
@@ -236,7 +266,6 @@ func ArArray(arr []any) ArObject {
} }
} }
arr = append(arr[:num], append(args[1:], arr[num:]...)...) arr = append(arr[:num], append(args[1:], arr[num:]...)...)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr val.obj["__value__"] = arr
return nil, ArErr{} return nil, ArErr{}
}, },
@@ -276,13 +305,11 @@ func ArArray(arr []any) ArObject {
} }
v := arr[num] v := arr[num]
arr = append(arr[:num], arr[num+1:]...) arr = append(arr[:num], arr[num+1:]...)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr val.obj["__value__"] = arr
return v, ArErr{} return v, ArErr{}
} }
v := arr[len(arr)-1] v := arr[len(arr)-1]
arr = arr[:len(arr)-1] arr = arr[:len(arr)-1]
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr val.obj["__value__"] = arr
return v, ArErr{} return v, ArErr{}
}, },
@@ -298,7 +325,6 @@ func ArArray(arr []any) ArObject {
} }
} }
arr = []any{} arr = []any{}
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr val.obj["__value__"] = arr
return nil, ArErr{} return nil, ArErr{}
}, },
@@ -321,7 +347,6 @@ func ArArray(arr []any) ArObject {
} }
} }
arr = append(arr, args[0].(ArObject).obj["__value__"].([]any)...) arr = append(arr, args[0].(ArObject).obj["__value__"].([]any)...)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr val.obj["__value__"] = arr
return nil, ArErr{} return nil, ArErr{}
}, },
@@ -370,7 +395,6 @@ func ArArray(arr []any) ArObject {
} }
} }
arr = output arr = output
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr val.obj["__value__"] = arr
return nil, ArErr{} return nil, ArErr{}
} }
@@ -386,7 +410,6 @@ func ArArray(arr []any) ArObject {
} }
} }
arr = output arr = output
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr val.obj["__value__"] = arr
return nil, ArErr{} return nil, ArErr{}
}, },

View File

@@ -6,18 +6,11 @@ import (
var bracketsCompile = makeRegex(`( *)\((.|\n)+\)( *)`) var bracketsCompile = makeRegex(`( *)\((.|\n)+\)( *)`)
type brackets struct {
VAL any
line int
code string
path string
}
func isBrackets(code UNPARSEcode) bool { func isBrackets(code UNPARSEcode) bool {
return bracketsCompile.MatchString(code.code) return bracketsCompile.MatchString(code.code)
} }
func parseBrackets(code UNPARSEcode, index int, codeline []UNPARSEcode) (brackets, bool, ArErr, int) { func parseBrackets(code UNPARSEcode, index int, codeline []UNPARSEcode) (any, bool, ArErr, int) {
trimmed := strings.TrimSpace(code.code) trimmed := strings.TrimSpace(code.code)
resp, worked, err, i := translateVal(UNPARSEcode{ resp, worked, err, i := translateVal(UNPARSEcode{
code: trimmed[1 : len(trimmed)-1], code: trimmed[1 : len(trimmed)-1],
@@ -25,10 +18,5 @@ func parseBrackets(code UNPARSEcode, index int, codeline []UNPARSEcode) (bracket
line: code.line, line: code.line,
path: code.path, path: code.path,
}, index, codeline, 0) }, index, codeline, 0)
return brackets{ return resp, worked, err, i
VAL: resp,
line: code.line,
code: code.realcode,
path: code.path,
}, worked, err, i
} }

View File

@@ -86,7 +86,6 @@ func ArBuffer(buf []byte) ArObject {
obj: anymap{ obj: anymap{
"__name__": "buffer", "__name__": "buffer",
"__value__": buf, "__value__": buf,
"length": newNumber().SetInt64(int64(len(buf))),
}, },
} }
obj.obj["__string__"] = builtinFunc{ obj.obj["__string__"] = builtinFunc{
@@ -147,7 +146,6 @@ func ArBuffer(buf []byte) ArObject {
} }
} }
obj.obj["__value__"] = buf obj.obj["__value__"] = buf
obj.obj["length"] = newNumber().SetInt64(int64(len(buf)))
return obj, ArErr{} return obj, ArErr{}
}, },
} }
@@ -390,7 +388,6 @@ func ArBuffer(buf []byte) ArObject {
} }
} }
obj.obj["__value__"] = buf obj.obj["__value__"] = buf
obj.obj["length"] = newNumber().SetInt64(int64(len(buf)))
return obj, ArErr{} return obj, ArErr{}
}, },
} }
@@ -464,10 +461,56 @@ func ArBuffer(buf []byte) ArObject {
} }
} }
obj.obj["__value__"] = buf obj.obj["__value__"] = buf
obj.obj["length"] = newNumber().SetInt64(int64(len(buf)))
return obj, ArErr{} return obj, ArErr{}
}, },
} }
obj.obj["__getindex__"] = builtinFunc{
"__getindex__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{
TYPE: "Type Error",
message: "expected 1 argument, got " + fmt.Sprint(len(a)),
EXISTS: true,
}
}
{
if len(a) == 1 {
if typeof(a[0]) == "string" {
var name = ArValidToAny(a[0]).(string)
if name == "length" {
return newNumber().SetInt64(int64(len(buf))), ArErr{}
}
}
}
}
poss := ArValidToAny(a[0])
if typeof(poss) != "number" {
return nil, ArErr{
TYPE: "Type Error",
message: "expected number, got " + typeof(poss),
EXISTS: true,
}
}
pos := poss.(number)
if pos.Denom().Cmp(one.Denom()) != 0 {
return nil, ArErr{
TYPE: "Type Error",
message: "position must be an integer",
EXISTS: true,
}
}
posNum := pos.Num().Int64()
if posNum < 0 || posNum >= int64(len(buf)) {
return nil, ArErr{
TYPE: "Index Error",
message: "index out of range",
EXISTS: true,
}
}
return ArByte(buf[posNum]), ArErr{}
},
}
obj.obj["remove"] = builtinFunc{ obj.obj["remove"] = builtinFunc{
"remove", "remove",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
@@ -497,7 +540,6 @@ func ArBuffer(buf []byte) ArObject {
posNum := pos.Num().Int64() posNum := pos.Num().Int64()
buf = append(buf[:posNum], buf[posNum+1:]...) buf = append(buf[:posNum], buf[posNum+1:]...)
obj.obj["__value__"] = buf obj.obj["__value__"] = buf
obj.obj["length"] = newNumber().SetInt64(int64(len(buf)))
return obj, ArErr{} return obj, ArErr{}
}, },
} }

View File

@@ -9,8 +9,10 @@ func makeGlobal() ArObject {
var vars = anymap{} var vars = anymap{}
vars["global"] = vars vars["global"] = vars
vars["env"] = env vars["env"] = env
vars["platform"] = platform
vars["term"] = ArTerm vars["term"] = ArTerm
vars["ArgonVersion"] = ArString(VERSION) vars["ArgonVersion"] = ArString(VERSION)
vars["ArgonVersionNumber"] = newNumber().SetInt64(VERSION_NUM)
vars["number"] = builtinFunc{"number", ArgonNumber} vars["number"] = builtinFunc{"number", ArgonNumber}
vars["string"] = builtinFunc{"string", ArgonString} vars["string"] = builtinFunc{"string", ArgonString}
vars["socket"] = Map(anymap{ vars["socket"] = Map(anymap{
@@ -18,6 +20,7 @@ func makeGlobal() ArObject {
"client": builtinFunc{"client", ArSocketClient}, "client": builtinFunc{"client", ArSocketClient},
}) })
vars["infinity"] = infinity vars["infinity"] = infinity
vars["eval"] = builtinFunc{"eval", AReval}
vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) { vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {
return Map(anymap{}), ArErr{} return Map(anymap{}), ArErr{}
@@ -49,7 +52,12 @@ func makeGlobal() ArObject {
} }
return Map(newmap), ArErr{} return Map(newmap), ArErr{}
} }
return x, ArErr{}
newmap := anymap{}
for key, val := range x.obj {
newmap[key] = val
}
return Map(newmap), ArErr{}
} }
return nil, ArErr{TYPE: "Type Error", message: "Cannot create map from '" + typeof(a[0]) + "'", EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Cannot create map from '" + typeof(a[0]) + "'", EXISTS: true}
}} }}
@@ -74,6 +82,12 @@ func makeGlobal() ArObject {
} }
return ArBuffer([]byte{}), ArErr{} return ArBuffer([]byte{}), ArErr{}
}} }}
vars["byte"] = builtinFunc{"byte", func(a ...any) (any, ArErr) {
if len(a) != 0 {
return nil, ArErr{TYPE: "Type Error", message: "expected 0 arguments, got " + fmt.Sprint(len(a)), EXISTS: true}
}
return ArByte(0), ArErr{}
}}
vars["throwError"] = builtinFunc{"throwError", ArThrowError} vars["throwError"] = builtinFunc{"throwError", ArThrowError}
vars["array"] = builtinFunc{"array", func(a ...any) (any, ArErr) { vars["array"] = builtinFunc{"array", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {
@@ -224,7 +238,7 @@ func makeGlobal() ArObject {
}} }}
vars["subprocess"] = builtinFunc{"subprocess", ArSubprocess} vars["subprocess"] = builtinFunc{"subprocess", ArSubprocess}
vars["sequence"] = builtinFunc{"sequence", ArSequence} vars["sequence"] = builtinFunc{"sequence", ArSequence}
vars["|"] = builtinFunc{"exit", func(a ...any) (any, ArErr) { vars["exit"] = builtinFunc{"exit", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {
os.Exit(0) os.Exit(0)
} }
@@ -253,7 +267,7 @@ func makeGlobal() ArObject {
switch x := a[0].(type) { switch x := a[0].(type) {
case string: case string:
if len(x) != 1 { if len(x) != 1 {
return nil, ArErr{TYPE: "ord", message: "ord takes a string with only one character, got " + fmt.Sprint(len(a)), EXISTS: true} return nil, ArErr{TYPE: "ord", message: "ord takes a string with only one character, got " + fmt.Sprint(len(x)), EXISTS: true}
} }
return floor(newNumber().SetInt64(int64([]rune(x)[0]))), ArErr{} return floor(newNumber().SetInt64(int64([]rune(x)[0]))), ArErr{}
} }

View File

@@ -20,11 +20,11 @@ func isDoWrap(code UNPARSEcode) bool {
func parseDoWrap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr, int) { func parseDoWrap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr, int) {
currentindent := len(code.realcode) - len(strings.TrimLeft(code.realcode, " ")) currentindent := len(code.realcode) - len(strings.TrimLeft(code.realcode, " "))
var setindent int = -1 var setindent int = -1
var i = index + 1 var allCodelines = []UNPARSEcode{}
translated := []any{} i := index + 1
for i < len(codelines) { for ; i < len(codelines); i++ {
if isBlank(codelines[i]) { if isBlank(codelines[i]) {
i++
continue continue
} }
indent := len(codelines[i].code) - len(strings.TrimLeft(codelines[i].code, " ")) indent := len(codelines[i].code) - len(strings.TrimLeft(codelines[i].code, " "))
@@ -34,8 +34,15 @@ func parseDoWrap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, boo
if indent <= currentindent { if indent <= currentindent {
break break
} }
allCodelines = append(allCodelines, codelines[i])
}
finalLines := i
codelines = allCodelines
translated := []any{}
for i := 0; i < len(codelines); {
indent := len(codelines[i].code) - len(strings.TrimLeft(codelines[i].code, " "))
if indent != setindent { if indent != setindent {
return nil, false, ArErr{"Syntax Error", "invalid indent", i, code.path, codelines[i].code, true}, 1 return nil, false, ArErr{"Syntax Error", "invalid indent", code.line, code.path, codelines[i].code, true}, 1
} }
val, _, err, step := translateVal(codelines[i], i, codelines, 3) val, _, err, step := translateVal(codelines[i], i, codelines, 3)
@@ -45,13 +52,15 @@ func parseDoWrap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, boo
} }
translated = append(translated, val) translated = append(translated, val)
} }
return dowrap{run: translated, line: code.line, path: code.path, code: code.realcode}, true, ArErr{}, i - index return dowrap{run: translated, line: code.line, path: code.path, code: code.realcode}, true, ArErr{}, finalLines - index
} }
func runDoWrap(d dowrap, stack stack, stacklevel int) (any, ArErr) { func runDoWrap(d dowrap, Stack stack, stacklevel int) (any, ArErr) {
newstack := append(stack, newscope()) newstack := append(Stack, newscope())
newstackCopy := make(stack, len(newstack))
copy(newstackCopy, newstack)
for _, v := range d.run { for _, v := range d.run {
val, err := runVal(v, newstack, stacklevel+1) val, err := runVal(v, newstackCopy, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }

41
src/eval_function.go Normal file
View File

@@ -0,0 +1,41 @@
package main
import "fmt"
func AReval(a ...any) (any, ArErr) {
if len(a) < 1 || len(a) > 2 {
return nil, ArErr{TYPE: "Type Error", message: "expected 1 or 2 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
}
var expression string
if typeof(a[0]) != "string" {
return nil, ArErr{TYPE: "Type Error", message: "expected string as first argument, got " + typeof(a[0]), EXISTS: true}
}
expression = ArValidToAny(a[0]).(string)
// translate the expression
var code UNPARSEcode = UNPARSEcode{
code: expression,
realcode: expression,
line: 0,
path: "eval",
}
translated, err := translate([]UNPARSEcode{code})
if err.EXISTS {
return nil, err
}
var scope ArObject
if len(a) == 2 {
if typeof(a[1]) != "map" {
return nil, ArErr{TYPE: "Type Error", message: "expected map as second argument, got " + typeof(a[1]), EXISTS: true}
}
scope = a[1].(ArObject)
} else {
scope = newscope()
}
var stack stack = []ArObject{scope}
// run the translated expression
return run(translated, stack)
}

View File

@@ -12,8 +12,73 @@ import (
var ArFile = Map(anymap{ var ArFile = Map(anymap{
"read": builtinFunc{"read", ArRead}, "read": builtinFunc{"read", ArRead},
"write": builtinFunc{"write", ArWrite}, "write": builtinFunc{"write", ArWrite},
"move": builtinFunc{"move", ARmoveFile},
"copy": builtinFunc{"copy", ARcopyFile},
}) })
func ARmoveFile(args ...any) (any, ArErr) {
if len(args) != 2 {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "move takes 2 arguments, got " + fmt.Sprint(len(args)), EXISTS: true}
}
if typeof(args[0]) != "string" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "move takes a string not type '" + typeof(args[0]) + "'", EXISTS: true}
}
if typeof(args[1]) != "string" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "move takes a string not type '" + typeof(args[1]) + "'", EXISTS: true}
}
args[0] = ArValidToAny(args[0])
args[1] = ArValidToAny(args[1])
err := os.Rename(args[0].(string), args[1].(string))
if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return nil, ArErr{}
}
func copyFile(src, dst string) (int64, error) {
sourceFileStat, err := os.Stat(src)
if err != nil {
return 0, err
}
if !sourceFileStat.Mode().IsRegular() {
return 0, fmt.Errorf("%s is not a regular file", src)
}
source, err := os.Open(src)
if err != nil {
return 0, err
}
defer source.Close()
destination, err := os.Create(dst)
if err != nil {
return 0, err
}
defer destination.Close()
nBytes, err := io.Copy(destination, source)
return nBytes, err
}
func ARcopyFile(args ...any) (any, ArErr) {
if len(args) != 2 {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "copy takes 2 arguments, got " + fmt.Sprint(len(args)), EXISTS: true}
}
if typeof(args[0]) != "string" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "copy takes a string not type '" + typeof(args[0]) + "'", EXISTS: true}
}
if typeof(args[1]) != "string" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "copy takes a string not type '" + typeof(args[1]) + "'", EXISTS: true}
}
args[0] = ArValidToAny(args[0])
args[1] = ArValidToAny(args[1])
_, err := copyFile(args[0].(string), args[1].(string))
if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return nil, ArErr{}
}
func readtext(file *os.File) (string, error) { func readtext(file *os.File) (string, error) {
var buf bytes.Buffer var buf bytes.Buffer
_, err := io.Copy(&buf, file) _, err := io.Copy(&buf, file)
@@ -70,7 +135,7 @@ func ArRead(args ...any) (any, ArErr) {
if err != nil { if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true} return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
} }
return jsonparse(text), ArErr{} return jsonparse(text)
}}, }},
"contentType": builtinFunc{"contentType", func(...any) (any, ArErr) { "contentType": builtinFunc{"contentType", func(...any) (any, ArErr) {
file.Seek(0, io.SeekStart) file.Seek(0, io.SeekStart)

View File

@@ -63,7 +63,7 @@ func parseForLoop(code UNPARSEcode, index int, codelines []UNPARSEcode) (forLoop
} }
innertotalstep += tostep - 1 innertotalstep += tostep - 1
body := strings.Join(tosplit[i:], ")") body := strings.Join(tosplit[i:], ")")
bodyval, worked, err, bodystep := translateVal(UNPARSEcode{code: body, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 1) bodyval, worked, err, bodystep := translateVal(UNPARSEcode{code: body, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 3)
if !worked { if !worked {
if i == 0 { if i == 0 {
return forLoop{}, worked, err, bodystep return forLoop{}, worked, err, bodystep

View File

@@ -32,6 +32,7 @@ func parseIfStatement(code UNPARSEcode, index int, codeline []UNPARSEcode) (ifst
conditions := []statement{} conditions := []statement{}
var ELSE any var ELSE any
i := index i := index
codeline[i] = code
for i < len(codeline) && (elseifstatmentCompile.MatchString(codeline[i].code) || i == index) { for i < len(codeline) && (elseifstatmentCompile.MatchString(codeline[i].code) || i == index) {
trimmed := strings.TrimSpace(codeline[i].code) trimmed := strings.TrimSpace(codeline[i].code)
trimmed = strings.TrimSpace(trimmed[strings.Index(trimmed, "("):]) trimmed = strings.TrimSpace(trimmed[strings.Index(trimmed, "("):])
@@ -69,7 +70,7 @@ func parseIfStatement(code UNPARSEcode, index int, codeline []UNPARSEcode) (ifst
}, },
i, i,
codeline, codeline,
2, 3,
) )
if err.EXISTS || !worked { if err.EXISTS || !worked {
return ifstatement{}, worked, err, step return ifstatement{}, worked, err, step
@@ -98,7 +99,7 @@ func parseIfStatement(code UNPARSEcode, index int, codeline []UNPARSEcode) (ifst
}, },
i, i,
codeline, codeline,
2, 3,
) )
if err.EXISTS { if err.EXISTS {
return ifstatement{}, false, err, step return ifstatement{}, false, err, step

View File

@@ -7,6 +7,7 @@ import (
) )
var imported = make(map[string]ArObject) var imported = make(map[string]ArObject)
var translatedImports = make(map[string]translatedImport)
var importing = make(map[string]bool) var importing = make(map[string]bool)
const modules_folder = "argon_modules" const modules_folder = "argon_modules"
@@ -41,67 +42,31 @@ func readFile(path string) ([]UNPARSEcode, error) {
return output, nil return output, nil
} }
func importMod(realpath string, origin string, main bool, global ArObject) (ArObject, ArErr) { type translatedImport struct {
extention := filepath.Ext(realpath) translated []any
path := realpath p string
if extention == "" { path string
path += ".ar" origin string
}
ex, err := os.Getwd()
if err != nil {
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not get working directory", EXISTS: true}
}
exc, err := os.Executable()
if err != nil {
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not get executable", EXISTS: true}
}
executable := filepath.Dir(exc)
isABS := filepath.IsAbs(path)
var pathsToTest []string
if isABS {
pathsToTest = []string{
filepath.Join(path),
filepath.Join(realpath, "init.ar"),
}
} else {
pathsToTest = []string{
filepath.Join(origin, path),
filepath.Join(origin, realpath, "init.ar"),
filepath.Join(origin, modules_folder, path),
filepath.Join(origin, modules_folder, realpath, "init.ar"),
filepath.Join(ex, path),
filepath.Join(ex, modules_folder, path),
filepath.Join(ex, modules_folder, realpath, "init.ar"),
filepath.Join(executable, modules_folder, path),
filepath.Join(executable, modules_folder, realpath, "init.ar"),
}
}
var p string
var found bool
for _, p = range pathsToTest {
if FileExists(p) {
found = true
break
}
} }
if !found { var runTranslatedImport func(translatedImport, ArObject, bool) (ArObject, ArErr)
return ArObject{}, ArErr{TYPE: "Import Error", message: "File does not exist: " + path, EXISTS: true} var ex string
} else if importing[p] { var exc string
return ArObject{}, ArErr{TYPE: "Import Error", message: "Circular import: " + path, EXISTS: true} var exc_dir string
} else if _, ok := imported[p]; ok {
return imported[p], ArErr{}
}
importing[p] = true
codelines, err := readFile(p)
if err != nil {
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not read file: " + path, EXISTS: true}
}
translated, translationerr := translate(codelines)
if translationerr.EXISTS { func init() {
return ArObject{}, translationerr runTranslatedImport = __runTranslatedImport
ex, _ = os.Getwd()
exc, _ = os.Executable()
exc_dir = filepath.Dir(exc)
} }
func __runTranslatedImport(translatedImport translatedImport, global ArObject, main bool) (ArObject, ArErr) {
if _, ok := imported[translatedImport.p]; ok {
return imported[translatedImport.p], ArErr{}
}
ArgsArArray := []any{} ArgsArArray := []any{}
withoutarfile := []string{} withoutarfile := []string{}
if len(Args) > 1 { if len(Args) > 1 {
@@ -114,30 +79,90 @@ func importMod(realpath string, origin string, main bool, global ArObject) (ArOb
localvars := Map(anymap{ localvars := Map(anymap{
"program": Map(anymap{ "program": Map(anymap{
"args": ArArray(ArgsArArray), "args": ArArray(ArgsArArray),
"origin": ArString(origin), "origin": ArString(translatedImport.origin),
"import": builtinFunc{"import", func(args ...any) (any, ArErr) {
if len(args) != 1 {
return nil, ArErr{"Import Error", "Invalid number of arguments", 0, realpath, "", true}
}
if _, ok := args[0].(string); !ok {
return nil, ArErr{"Import Error", "Invalid argument type", 0, realpath, "", true}
}
return importMod(args[0].(string), filepath.Dir(filepath.ToSlash(p)), false, global)
}},
"cwd": ArString(ex), "cwd": ArString(ex),
"exc": ArString(exc), "exc": ArString(exc),
"file": Map(anymap{ "file": Map(anymap{
"name": ArString(filepath.Base(p)), "name": ArString(filepath.Base(translatedImport.p)),
"path": ArString(p), "path": ArString(translatedImport.p),
}), }),
"main": main, "main": main,
}), }),
}) })
_, runimeErr := run(translated, stack{global, localvars, local}) imported[translatedImport.p] = local
importing[p] = false _, runimeErr := run(translatedImport.translated, stack{global, localvars, local})
if runimeErr.EXISTS { if runimeErr.EXISTS {
return ArObject{}, runimeErr return ArObject{}, runimeErr
} }
imported[p] = local
return local, ArErr{} return local, ArErr{}
} }
func translateImport(realpath string, origin string, topLevelOnly bool) (translatedImport, ArErr) {
extention := filepath.Ext(realpath)
path := realpath
if extention == "" {
path += ".ar"
}
isABS := filepath.IsAbs(path)
var pathsToTest []string
if isABS {
pathsToTest = []string{
filepath.Join(path),
filepath.Join(realpath, "init.ar"),
}
} else {
pathsToTest = []string{
filepath.Join(exc_dir, path),
filepath.Join(exc_dir, realpath, "init.ar"),
filepath.Join(exc_dir, modules_folder, path),
filepath.Join(exc_dir, modules_folder, realpath, "init.ar"),
}
var currentPath string = origin
var oldPath string = ""
for currentPath != oldPath {
pathsToTest = append(pathsToTest,
filepath.Join(currentPath, path),
filepath.Join(currentPath, realpath, "init.ar"),
filepath.Join(currentPath, modules_folder, path),
filepath.Join(currentPath, modules_folder, realpath, "init.ar"))
if topLevelOnly {
break
}
oldPath = currentPath
currentPath = filepath.Dir(currentPath)
}
}
var p string
var found bool
for _, p = range pathsToTest {
if FileExists(p) {
found = true
break
}
}
if !found {
return translatedImport{}, ArErr{TYPE: "Import Error", message: "File does not exist: " + path, EXISTS: true}
} else if importing[p] {
return translatedImport{}, ArErr{TYPE: "Import Error", message: "Circular import: " + path, EXISTS: true}
} else if _, ok := translatedImports[p]; ok {
return translatedImports[p], ArErr{}
}
importing[p] = true
codelines, err := readFile(p)
if err != nil {
return translatedImport{}, ArErr{TYPE: "Import Error", message: "Could not read file: " + path, EXISTS: true}
}
importing[p] = true
translated, translationerr := translate(codelines)
debugPrintln(translated...)
importing[p] = false
if translationerr.EXISTS {
return translatedImport{}, translationerr
}
translatedImports[p] = translatedImport{translated, p, path, origin}
return translatedImports[p], ArErr{}
}

View File

@@ -1,63 +1,13 @@
package main package main
import ( import (
"bufio"
"fmt" "fmt"
"os" "os"
"golang.org/x/term" "golang.org/x/term"
) )
func input(args ...any) string { var tempFilePath = os.TempDir() + "/argon_input_history.tmp"
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
fmt.Print(output...)
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
input := scanner.Text()
return input
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
fmt.Print(output...)
password := []byte{}
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
defer term.Restore(int(os.Stdin.Fd()), oldState)
for {
char := make([]byte, 1)
_, err := os.Stdin.Read(char)
if err != nil {
return "", err
}
if char[0] == 3 || char[0] == 4 {
return "", fmt.Errorf("keyboard interupt")
} else if char[0] == '\r' || char[0] == '\n' {
fmt.Println()
break
} else if char[0] == '\b' || char[0] == 127 {
if len(password) > 0 {
password = password[:len(password)-1]
fmt.Print("\b \b")
}
} else {
password = append(password, char[0])
fmt.Print("*")
}
}
fmt.Print("\r")
return string(password), nil
}
func pause() { func pause() {
fmt.Print("Press Enter to continue...") fmt.Print("Press Enter to continue...")

55
src/input_unix.go Normal file
View File

@@ -0,0 +1,55 @@
//go:build !WINDOWS
// +build !WINDOWS
package main
import (
"fmt"
"log"
"github.com/chzyer/readline"
)
func input(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
HistoryFile: tempFilePath,
HistorySearchFold: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
MaskRune: '*',
EnableMask: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}

63
src/input_windows.go Normal file
View File

@@ -0,0 +1,63 @@
//go:build WINDOWS
// +build WINDOWS
package main
import (
"bufio"
"fmt"
"os"
"golang.org/x/term"
)
func input(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
fmt.Print(output...)
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
input := scanner.Text()
return input, nil
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
fmt.Print(output...)
password := []byte{}
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
defer term.Restore(int(os.Stdin.Fd()), oldState)
for {
char := make([]byte, 1)
_, err := os.Stdin.Read(char)
if err != nil {
return "", err
}
if char[0] == 3 || char[0] == 4 {
return "", fmt.Errorf("keyboard interupt")
} else if char[0] == '\r' || char[0] == '\n' {
fmt.Println()
break
} else if char[0] == '\b' || char[0] == 127 {
if len(password) > 0 {
password = password[:len(password)-1]
fmt.Print("\b \b")
}
} else {
password = append(password, char[0])
fmt.Print("*")
}
}
fmt.Print("\r")
return string(password), nil
}

View File

@@ -33,10 +33,11 @@ func convertToArgon(obj any) any {
return nil return nil
} }
func jsonparse(str string) any { func jsonparse(str string) (any, ArErr) {
var jsonMap any var jsonMap any
json.Unmarshal([]byte(str), &jsonMap) var err = json.Unmarshal([]byte(str), &jsonMap)
return convertToArgon(jsonMap) if err != nil {return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}}
return convertToArgon(jsonMap), ArErr{}
} }
func jsonstringify(obj any, level int) (string, error) { func jsonstringify(obj any, level int) (string, error) {
@@ -90,7 +91,7 @@ var ArJSON = Map(anymap{
return nil, ArErr{TYPE: "Runtime Error", message: "parse takes a string not a '" + typeof(args[0]) + "'", EXISTS: true} return nil, ArErr{TYPE: "Runtime Error", message: "parse takes a string not a '" + typeof(args[0]) + "'", EXISTS: true}
} }
args[0] = ArValidToAny(args[0]) args[0] = ArValidToAny(args[0])
return jsonparse(args[0].(string)), ArErr{} return jsonparse(args[0].(string))
}}, }},
"stringify": builtinFunc{"stringify", func(args ...any) (any, ArErr) { "stringify": builtinFunc{"stringify", func(args ...any) (any, ArErr) {
if len(args) == 0 { if len(args) == 0 {

View File

@@ -10,13 +10,8 @@ var Args = os.Args[1:]
type stack = []ArObject type stack = []ArObject
const VERSION = "3.0.1" const VERSION = "3.0.11"
const VERSION_NUM = 9
// Example struct
type Person struct {
Name string
Age int
}
func newscope() ArObject { func newscope() ArObject {
return Map(anymap{}) return Map(anymap{})
@@ -61,12 +56,15 @@ func main() {
if e != nil { if e != nil {
panic(e) panic(e)
} }
_, err := importMod(Args[0], ex, true, global) translated, err := translateImport(Args[0], ex, true)
if err.EXISTS { if err.EXISTS {
panicErr(err) panicErr(err)
os.Exit(1) os.Exit(1)
} }
if threadCount > 0 { _, runimeErr := runTranslatedImport(translated, global, true)
<-threadChan if runimeErr.EXISTS {
panicErr(runimeErr)
os.Exit(1)
} }
threadChan.Wait()
} }

View File

@@ -114,18 +114,17 @@ func parseMap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
}, true, ArErr{}, countIndex }, true, ArErr{}, countIndex
} }
func Map(m anymap) ArObject {
var mutex = sync.RWMutex{} var mutex = sync.RWMutex{}
var listenersMutex = sync.RWMutex{} var listenersMutex = sync.RWMutex{}
func Map(m anymap) ArObject {
var currentID uint32 = 0 var currentID uint32 = 0
listeners := map[any]map[uint32]any{} listeners := map[any]map[uint32]any{}
obj := ArObject{ obj := ArObject{
obj: anymap{ obj: anymap{
"__value__": m, "__value__": m,
"__name__": "map", "__name__": "map",
"get": builtinFunc{ "get_value": builtinFunc{
"get", "get_value",
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
if len(args) < 1 || len(args) > 2 { if len(args) < 1 || len(args) > 2 {
return nil, ArErr{ return nil, ArErr{
@@ -274,6 +273,54 @@ func Map(m anymap) ArObject {
return nil, ArErr{} return nil, ArErr{}
}, },
}, },
"__deleteindex__": builtinFunc{
"__deleteindex__",
func(args ...any) (any, ArErr) {
if len(args) != 1 {
return nil, ArErr{
TYPE: "Type Error",
message: "expected 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true,
}
}
if isUnhashable(args[0]) {
return nil, ArErr{
TYPE: "Runtime Error",
message: "unhashable type: " + typeof(args[0]),
EXISTS: true,
}
}
key := ArValidToAny(args[0])
mutex.RLock()
if _, ok := m[key]; !ok {
mutex.RUnlock()
return nil, ArErr{
TYPE: "KeyError",
message: "key " + fmt.Sprint(key) + " not found",
EXISTS: true,
}
}
mutex.RUnlock()
listenersMutex.RLock()
if _, ok := listeners[key]; ok {
for _, v := range listeners[key] {
runCall(
call{
Callable: v,
Args: []any{},
},
stack{},
0,
)
}
}
listenersMutex.RUnlock()
mutex.Lock()
delete(m, key)
mutex.Unlock()
return nil, ArErr{}
},
},
"__getindex__": builtinFunc{ "__getindex__": builtinFunc{
"__getindex__", "__getindex__",
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
@@ -458,6 +505,7 @@ func Map(m anymap) ArObject {
return ArArray(keys), ArErr{} return ArArray(keys), ArErr{}
}, },
} }
obj.obj["__Boolean__"] = builtinFunc{ obj.obj["__Boolean__"] = builtinFunc{
"__Boolean__", "__Boolean__",
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {

View File

@@ -20,8 +20,8 @@ var operations = []string{
"==", "==",
"+", "+",
"-", "-",
"*",
"%", "%",
"*",
"//", "//",
"/", "/",
"^", "^",
@@ -82,7 +82,7 @@ func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (oper
operation: i, operation: i,
values: values, values: values,
line: code.line, line: code.line,
code: code.code, code: code.realcode,
path: code.path, path: code.path,
}, true, ArErr{}, totalStep }, true, ArErr{}, totalStep
} }
@@ -680,7 +680,7 @@ func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, A
} }
} }
if x, ok := b.(ArObject); ok { if x, ok := b.(ArObject); ok {
if y, ok := x.obj["__GreaterThanEqual__"]; ok { if y, ok := x.obj["__Equal__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
y, y,
@@ -918,9 +918,9 @@ func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
case 11: case 11:
return calcNegative(o, stack, stacklevel+1) return calcNegative(o, stack, stacklevel+1)
case 12: case 12:
return calcMul(o, stack, stacklevel+1)
case 13:
return calcMod(o, stack, stacklevel+1) return calcMod(o, stack, stacklevel+1)
case 13:
return calcMul(o, stack, stacklevel+1)
case 14: case 14:
return calcIntDiv(o, stack, stacklevel+1) return calcIntDiv(o, stack, stacklevel+1)
case 15: case 15:

View File

@@ -5,9 +5,11 @@ import (
"strings" "strings"
) )
var genericImportCompiled = makeRegex(`import( )+(.|\n)+(( )+as( )+([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*)?( *)`) var genericImportCompiled = makeRegex(`( *)import( )+(.|\n)+(( )+as( )+([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*)?( *)`)
type ArImport struct { type ArImport struct {
pretranslated bool
translated translatedImport
FilePath any FilePath any
Values any Values any
Code string Code string
@@ -67,16 +69,30 @@ func parseGenericImport(code UNPARSEcode, index int, codeline []UNPARSEcode) (Ar
} }
} }
return ArImport{ importOBJ := ArImport{
false,
translatedImport{},
toImport, toImport,
asStr, asStr,
code.realcode, code.realcode,
code.line, code.line,
code.path, code.path,
}, true, ArErr{}, i }
if str, ok := toImport.(string); ok {
resp, err := translateImport(str, filepath.Dir(filepath.ToSlash(code.path)), false)
if !err.EXISTS {
importOBJ.translated = resp
importOBJ.pretranslated = true
}
}
return importOBJ, true, ArErr{}, i
} }
func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) { func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) {
var translated = importOBJ.translated
if !importOBJ.pretranslated {
val, err := runVal(importOBJ.FilePath, stack, stacklevel+1) val, err := runVal(importOBJ.FilePath, stack, stacklevel+1)
val = ArValidToAny(val) val = ArValidToAny(val)
if err.EXISTS { if err.EXISTS {
@@ -85,9 +101,22 @@ func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) {
if typeof(val) != "string" { if typeof(val) != "string" {
return nil, ArErr{"Type Error", "import requires a string, got type '" + typeof(val) + "'", importOBJ.Line, importOBJ.Path, importOBJ.Code, true} return nil, ArErr{"Type Error", "import requires a string, got type '" + typeof(val) + "'", importOBJ.Line, importOBJ.Path, importOBJ.Code, true}
} }
path := val.(string)
parent := filepath.Dir(filepath.ToSlash(importOBJ.Path)) parent := filepath.Dir(filepath.ToSlash(importOBJ.Path))
stackMap, err := importMod(path, parent, false, stack[0]) translated, err = translateImport(val.(string), parent, false)
if err.EXISTS {
if err.line == 0 {
err.line = importOBJ.Line
}
if err.path == "" {
err.path = importOBJ.Path
}
if err.code == "" {
err.code = importOBJ.Code
}
return nil, err
}
}
stackMap, err := runTranslatedImport(translated, stack[0], false)
if err.EXISTS { if err.EXISTS {
if err.line == 0 { if err.line == 0 {
err.line = importOBJ.Line err.line = importOBJ.Line
@@ -116,7 +145,7 @@ func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) {
for _, v := range x { for _, v := range x {
val, ok := stackMap.obj[v] val, ok := stackMap.obj[v]
if !ok { if !ok {
return nil, ArErr{"Import Error", "could not find value " + anyToArgon(v, true, false, 3, 0, false, 0) + " in module " + anyToArgon(path, true, false, 3, 0, false, 0), importOBJ.Line, importOBJ.Path, importOBJ.Code, true} return nil, ArErr{"Import Error", "could not find value " + anyToArgon(v, true, false, 3, 0, false, 0) + " in module " + anyToArgon(translated.path, true, false, 3, 0, false, 0), importOBJ.Line, importOBJ.Path, importOBJ.Code, true}
} }
builtinCall(setindex, []any{v, val}) builtinCall(setindex, []any{v, val})
} }

View File

@@ -14,7 +14,7 @@ var ArPath = Map(
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "ReadDir takes exactly 1 argument, got " + fmt.Sprint(len(args)), message: "ReadDir takes exactly 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true, EXISTS: true,
} }
@@ -22,7 +22,7 @@ var ArPath = Map(
args[0] = ArValidToAny(args[0]) args[0] = ArValidToAny(args[0])
if typeof(args[0]) != "string" { if typeof(args[0]) != "string" {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "ReadDir argument must be a string, got " + typeof(args[0]), message: "ReadDir argument must be a string, got " + typeof(args[0]),
EXISTS: true, EXISTS: true,
} }
@@ -30,7 +30,7 @@ var ArPath = Map(
files, err := os.ReadDir(args[0].(string)) files, err := os.ReadDir(args[0].(string))
if err != nil { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: err.Error(), message: err.Error(),
EXISTS: true, EXISTS: true,
} }
@@ -46,7 +46,7 @@ var ArPath = Map(
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "exists takes exactly 1 argument, got " + fmt.Sprint(len(args)), message: "exists takes exactly 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true, EXISTS: true,
} }
@@ -54,7 +54,7 @@ var ArPath = Map(
args[0] = ArValidToAny(args[0]) args[0] = ArValidToAny(args[0])
if typeof(args[0]) != "string" { if typeof(args[0]) != "string" {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "exists argument must be a string, got " + typeof(args[0]), message: "exists argument must be a string, got " + typeof(args[0]),
EXISTS: true, EXISTS: true,
} }
@@ -65,7 +65,7 @@ var ArPath = Map(
return false, ArErr{} return false, ArErr{}
} }
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: err.Error(), message: err.Error(),
EXISTS: true, EXISTS: true,
} }
@@ -77,7 +77,7 @@ var ArPath = Map(
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "mkAllDir takes exactly 1 argument, got " + fmt.Sprint(len(args)), message: "mkAllDir takes exactly 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true, EXISTS: true,
} }
@@ -85,7 +85,7 @@ var ArPath = Map(
args[0] = ArValidToAny(args[0]) args[0] = ArValidToAny(args[0])
if typeof(args[0]) != "string" { if typeof(args[0]) != "string" {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "mkAllDir argument must be a string, got " + typeof(args[0]), message: "mkAllDir argument must be a string, got " + typeof(args[0]),
EXISTS: true, EXISTS: true,
} }
@@ -93,7 +93,7 @@ var ArPath = Map(
err := os.MkdirAll(args[0].(string), os.ModePerm) err := os.MkdirAll(args[0].(string), os.ModePerm)
if err != nil { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: err.Error(), message: err.Error(),
EXISTS: true, EXISTS: true,
} }
@@ -105,7 +105,7 @@ var ArPath = Map(
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "mkDir takes exactly 1 argument, got " + fmt.Sprint(len(args)), message: "mkDir takes exactly 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true, EXISTS: true,
} }
@@ -113,7 +113,7 @@ var ArPath = Map(
args[0] = ArValidToAny(args[0]) args[0] = ArValidToAny(args[0])
if typeof(args[0]) != "string" { if typeof(args[0]) != "string" {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "mkDir argument must be a string, got " + typeof(args[0]), message: "mkDir argument must be a string, got " + typeof(args[0]),
EXISTS: true, EXISTS: true,
} }
@@ -121,7 +121,7 @@ var ArPath = Map(
err := os.Mkdir(args[0].(string), os.ModePerm) err := os.Mkdir(args[0].(string), os.ModePerm)
if err != nil { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: err.Error(), message: err.Error(),
EXISTS: true, EXISTS: true,
} }
@@ -133,7 +133,7 @@ var ArPath = Map(
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "remove takes exactly 1 argument, got " + fmt.Sprint(len(args)), message: "remove takes exactly 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true, EXISTS: true,
} }
@@ -141,7 +141,7 @@ var ArPath = Map(
args[0] = ArValidToAny(args[0]) args[0] = ArValidToAny(args[0])
if typeof(args[0]) != "string" { if typeof(args[0]) != "string" {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "remove argument must be a string, got " + typeof(args[0]), message: "remove argument must be a string, got " + typeof(args[0]),
EXISTS: true, EXISTS: true,
} }
@@ -149,7 +149,7 @@ var ArPath = Map(
err := os.Remove(args[0].(string)) err := os.Remove(args[0].(string))
if err != nil { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: err.Error(), message: err.Error(),
EXISTS: true, EXISTS: true,
} }
@@ -161,7 +161,7 @@ var ArPath = Map(
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "isDir takes exactly 1 argument, got " + fmt.Sprint(len(args)), message: "isDir takes exactly 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true, EXISTS: true,
} }
@@ -169,7 +169,7 @@ var ArPath = Map(
args[0] = ArValidToAny(args[0]) args[0] = ArValidToAny(args[0])
if typeof(args[0]) != "string" { if typeof(args[0]) != "string" {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "isDir argument must be a string, got " + typeof(args[0]), message: "isDir argument must be a string, got " + typeof(args[0]),
EXISTS: true, EXISTS: true,
} }
@@ -180,7 +180,7 @@ var ArPath = Map(
return false, ArErr{} return false, ArErr{}
} }
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: err.Error(), message: err.Error(),
EXISTS: true, EXISTS: true,
} }
@@ -192,7 +192,7 @@ var ArPath = Map(
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "join takes exactly 1 argument, got " + fmt.Sprint(len(args)), message: "join takes exactly 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true, EXISTS: true,
} }
@@ -205,7 +205,7 @@ var ArPath = Map(
x = ArValidToAny(x) x = ArValidToAny(x)
if typeof(x) != "string" { if typeof(x) != "string" {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "join argument must be an array of strings, got " + typeof(x), message: "join argument must be an array of strings, got " + typeof(x),
EXISTS: true, EXISTS: true,
} }
@@ -215,7 +215,7 @@ var ArPath = Map(
return filepath.Join(Path...), ArErr{} return filepath.Join(Path...), ArErr{}
} }
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "join argument must be an array, got " + typeof(args[0]), message: "join argument must be an array, got " + typeof(args[0]),
EXISTS: true, EXISTS: true,
} }
@@ -225,7 +225,7 @@ var ArPath = Map(
func(args ...any) (any, ArErr) { func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "parent takes exactly 1 argument, got " + fmt.Sprint(len(args)), message: "parent takes exactly 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true, EXISTS: true,
} }
@@ -233,7 +233,7 @@ var ArPath = Map(
args[0] = ArValidToAny(args[0]) args[0] = ArValidToAny(args[0])
if typeof(args[0]) != "string" { if typeof(args[0]) != "string" {
return nil, ArErr{ return nil, ArErr{
TYPE: "runtime", TYPE: "Runtime Error",
message: "parent argument must be a string, got " + typeof(args[0]), message: "parent argument must be a string, got " + typeof(args[0]),
EXISTS: true, EXISTS: true,
} }

49
src/platform.go Normal file
View File

@@ -0,0 +1,49 @@
package main
import (
"fmt"
"runtime"
"time"
"github.com/shirou/gopsutil/cpu"
)
var platform = Map(
anymap{
"os": ArString(runtime.GOOS),
"cpu": Map(anymap{
"count": newNumber().SetInt64((int64)(runtime.NumCPU())),
"usage": builtinFunc{"usage", func(args ...any) (any, ArErr) {
if len(args) != 2 {
return nil, ArErr{
TYPE: "Runtime Error",
message: "usage takes 2 arguments, got " + fmt.Sprint(len(args)),
EXISTS: true,
}
}
if !isAnyNumber(args[0]) {
return nil, ArErr{
TYPE: "Runtime Error",
message: "first argument is meant to be a number, got " + fmt.Sprint(typeof(args[0])),
EXISTS: true,
}
}
var Number = newNumber().Mul(args[0].(number), newNumber().SetInt64(1000)).Num().Int64()
avgPercent, err := cpu.Percent(time.Duration(Number)*time.Millisecond, anyToBool(args[1]))
if err != nil {
return nil, ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
var ArAvgPercent = []any{}
for i := 0; i < len(avgPercent); i++ {
ArAvgPercent = append(ArAvgPercent, newNumber().SetFloat64(avgPercent[i]))
}
return ArArray(ArAvgPercent), ArErr{}
}},
}),
},
)

View File

@@ -80,14 +80,6 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
message: "cannot negate a non-number", message: "cannot negate a non-number",
EXISTS: true, EXISTS: true,
} }
case brackets:
if stackoverflow {
linenum = x.line
path = x.path
code = x.code
break
}
return runVal(x.VAL, stack, stacklevel+1)
case operationType: case operationType:
if stackoverflow { if stackoverflow {
linenum = x.line linenum = x.line

View File

@@ -14,12 +14,12 @@ func shell(global ArObject) {
go func() { go func() {
for sig := range c { for sig := range c {
if sig == os.Interrupt { if sig == os.Interrupt {
fmt.Println("\x1b[0m\n\x1b[32;5;240mBye :)\x1b[0m") fmt.Println("\x1b[0m\n\x1b[32;240mBye :)\x1b[0m")
os.Exit(0) os.Exit(0)
} }
} }
}() }()
fmt.Print("\x1b[32;5;240mWelcome to the Argon v3!\x1b[0m\n\n") fmt.Print("\x1b[32;240mWelcome to the Argon v3!\x1b[0m\n\n")
for { for {
indent := 0 indent := 0
previous := 0 previous := 0
@@ -27,13 +27,17 @@ func shell(global ArObject) {
textBefore := ">>>" textBefore := ">>>"
for i := 1; indent > 0 || (previous != indent && indent >= 0) || i == 1; i++ { for i := 1; indent > 0 || (previous != indent && indent >= 0) || i == 1; i++ {
indentStr := strings.Repeat(" ", indent) indentStr := strings.Repeat(" ", indent)
code := indentStr + input("\x1b[38;5;240m"+textBefore+indentStr+" \x1b[0m\x1b[1;5;240m") inp, err := input("\x1b[38;240m" + textBefore + indentStr + " \x1b[0m")
if err != nil {
fmt.Println("\x1b[0m\n\x1b[32;240mBye :)\x1b[0m")
os.Exit(0)
}
code := indentStr + inp
fmt.Print("\x1b[0m") fmt.Print("\x1b[0m")
totranslate = append(totranslate, UNPARSEcode{code, code, i, "<shell>"}) totranslate = append(totranslate, UNPARSEcode{code, code, i, "<shell>"})
trimmed := strings.TrimSpace(code) trimmed := strings.TrimSpace(code)
split := strings.Split(trimmed, " ")
previous = indent previous = indent
if split[len(split)-1] == "do" { if len(trimmed) >= 2 && trimmed[len(trimmed)-2:] == "do" {
indent++ indent++
} else if trimmed == "" { } else if trimmed == "" {
indent-- indent--

View File

@@ -65,7 +65,6 @@ func ArString(str string) ArObject {
anymap{ anymap{
"__value__": str, "__value__": str,
"__name__": "string", "__name__": "string",
"length": newNumber().SetUint64(uint64(len(str))),
}, },
} }
@@ -96,7 +95,6 @@ func ArString(str string) ArObject {
} }
str = strings.Join([]string{str[:index], a[1].(string), str[index+1:]}, "") str = strings.Join([]string{str[:index], a[1].(string), str[index+1:]}, "")
obj.obj["__value__"] = str obj.obj["__value__"] = str
obj.obj["length"] = newNumber().SetUint64(uint64(len(str)))
return nil, ArErr{} return nil, ArErr{}
}} }}
obj.obj["__getindex__"] = builtinFunc{ obj.obj["__getindex__"] = builtinFunc{
@@ -105,9 +103,19 @@ func ArString(str string) ArObject {
// a[0] is start // a[0] is start
// a[1] is end // a[1] is end
// a[2] is step // a[2] is step
if len(a) > 3 { if len(a) > 3 || len(a) == 0 {
return nil, ArErr{"Type Error", "expected 1 to 3 arguments, got " + fmt.Sprint(len(a)), 0, "", "", true} return nil, ArErr{"Type Error", "expected 1 to 3 arguments, got " + fmt.Sprint(len(a)), 0, "", "", true}
} }
{
if len(a) == 1 {
if typeof(a[0]) == "string" {
var name = ArValidToAny(a[0]).(string)
if name == "length" {
return newNumber().SetInt64(int64(len(str))), ArErr{}
}
}
}
}
var ( var (
start int = 0 start int = 0
end any = nil end any = nil
@@ -196,7 +204,6 @@ func ArString(str string) ArObject {
} }
str = strings.Join(output, "") str = strings.Join(output, "")
obj.obj["__value__"] = str obj.obj["__value__"] = str
obj.obj["length"] = newNumber().SetUint64(uint64(len(str)))
return nil, ArErr{} return nil, ArErr{}
}} }}
obj.obj["extend"] = builtinFunc{ obj.obj["extend"] = builtinFunc{
@@ -217,7 +224,6 @@ func ArString(str string) ArObject {
} }
str = strings.Join(output, "") str = strings.Join(output, "")
obj.obj["__value__"] = str obj.obj["__value__"] = str
obj.obj["length"] = newNumber().SetUint64(uint64(len(str)))
return nil, ArErr{} return nil, ArErr{}
}, },
} }
@@ -242,7 +248,6 @@ func ArString(str string) ArObject {
} }
str = str[:index] + a[1].(string) + str[index:] str = str[:index] + a[1].(string) + str[index:]
obj.obj["__value__"] = str obj.obj["__value__"] = str
obj.obj["length"] = newNumber().SetUint64(uint64(len(str)))
return nil, ArErr{} return nil, ArErr{}
}} }}
obj.obj["concat"] = builtinFunc{ obj.obj["concat"] = builtinFunc{
@@ -454,7 +459,6 @@ func ArString(str string) ArObject {
bytes[i] = b.(byte) bytes[i] = b.(byte)
} }
str = string(bytes) str = string(bytes)
obj.obj["length"] = newNumber().SetUint64(uint64(len(str)))
obj.obj["__value__"] = str obj.obj["__value__"] = str
return nil, ArErr{} return nil, ArErr{}
} }
@@ -474,7 +478,6 @@ func ArString(str string) ArObject {
bytes[i] = b.(byte) bytes[i] = b.(byte)
} }
str = string(bytes) str = string(bytes)
obj.obj["length"] = newNumber().SetUint64(uint64(len(str)))
obj.obj["__value__"] = str obj.obj["__value__"] = str
return nil, ArErr{} return nil, ArErr{}
}, },

View File

@@ -140,7 +140,15 @@ var ArInput = Map(
return ArString(resp), ArErr{} return ArString(resp), ArErr{}
}}, }},
"__call__": builtinFunc{"input", func(args ...any) (any, ArErr) { "__call__": builtinFunc{"input", func(args ...any) (any, ArErr) {
return input(args...), ArErr{} inp, err := input(args...)
if err != nil {
return nil, ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
return ArString(inp), ArErr{}
}}, }},
"pause": builtinFunc{"pause", func(args ...any) (any, ArErr) { "pause": builtinFunc{"pause", func(args ...any) (any, ArErr) {
pause() pause()

View File

@@ -2,10 +2,10 @@ package main
import ( import (
"fmt" "fmt"
"sync"
) )
var threadCount = 0 var threadChan = sync.WaitGroup{}
var threadChan = make(chan bool)
func ArThread(args ...any) (any, ArErr) { func ArThread(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
@@ -28,7 +28,7 @@ func ArThread(args ...any) (any, ArErr) {
hasrun := false hasrun := false
joined := false joined := false
var wg = make(chan bool) var wg = sync.WaitGroup{}
threadMap := Map(anymap{ threadMap := Map(anymap{
"start": builtinFunc{"start", func(args ...any) (any, ArErr) { "start": builtinFunc{"start", func(args ...any) (any, ArErr) {
if hasrun { if hasrun {
@@ -38,14 +38,12 @@ func ArThread(args ...any) (any, ArErr) {
return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true}
} }
hasrun = true hasrun = true
wg.Add(1)
threadChan.Add(1)
go func() { go func() {
threadCount++
resp, err = runCall(call{Callable: tocall, Args: []any{}}, nil, 0) resp, err = runCall(call{Callable: tocall, Args: []any{}}, nil, 0)
wg <- true wg.Done()
threadCount-- threadChan.Done()
if threadCount == 0 {
threadChan <- true
}
}() }()
return nil, ArErr{} return nil, ArErr{}
}}, }},
@@ -59,7 +57,7 @@ func ArThread(args ...any) (any, ArErr) {
return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true}
} }
joined = true joined = true
<-wg wg.Wait()
return resp, err return resp, err
}}, }},
}) })

View File

@@ -1,7 +1,6 @@
package main package main
import ( import (
"fmt"
"time" "time"
) )
@@ -195,7 +194,6 @@ var ArTime = Map(anymap{
}, },
}, },
"date": builtinFunc{"date", func(a ...any) (any, ArErr) { "date": builtinFunc{"date", func(a ...any) (any, ArErr) {
fmt.Println(a, len(a))
if len(a) == 1 { if len(a) == 1 {
if typeof(a[0]) != "string" { if typeof(a[0]) != "string" {
return nil, ArErr{ return nil, ArErr{

View File

@@ -42,7 +42,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
} }
case number: case number:
if colored { if colored {
output = append(output, "\x1b[34;5;240m") output = append(output, "\x1b[34;240m")
} }
num, _ := x.Float64() num, _ := x.Float64()
if math.IsNaN(num) { if math.IsNaN(num) {
@@ -59,7 +59,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
} }
case bool: case bool:
if colored { if colored {
output = append(output, "\x1b[35;5;240m") output = append(output, "\x1b[35;240m")
} }
output = append(output, strconv.FormatBool(x)) output = append(output, strconv.FormatBool(x))
if colored { if colored {
@@ -67,7 +67,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
} }
case nil: case nil:
if colored { if colored {
output = append(output, "\x1b[31;5;240m") output = append(output, "\x1b[31;240m")
} }
output = append(output, "null") output = append(output, "null")
if colored { if colored {
@@ -128,7 +128,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
} else { } else {
outputkeyval := []string{} outputkeyval := []string{}
if colored { if colored {
outputkeyval = append(outputkeyval, "\x1b[36;5;240m") outputkeyval = append(outputkeyval, "\x1b[36;240m")
} }
outputkeyval = append(outputkeyval, key.(string)) outputkeyval = append(outputkeyval, key.(string))
if colored { if colored {
@@ -148,7 +148,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
output = append(output, anyToArgon(item, true, true, depth-1, indent+1, colored, plain)) output = append(output, anyToArgon(item, true, true, depth-1, indent+1, colored, plain))
} }
if colored { if colored {
output = append(output, "\x1b[38;5;240m(...)\x1b[0m") output = append(output, "\x1b[38;240m(...)\x1b[0m")
} else { } else {
output = append(output, "(...)") output = append(output, "(...)")
} }
@@ -173,7 +173,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
return "[" + maybenewline + (strings.Repeat(" ", (indent+1)*plain)) + strings.Join(output, ","+maybenewline+(strings.Repeat(" ", (indent+1)*plain))) + maybenewline + (strings.Repeat(" ", indent*plain)) + "]" return "[" + maybenewline + (strings.Repeat(" ", (indent+1)*plain)) + strings.Join(output, ","+maybenewline+(strings.Repeat(" ", (indent+1)*plain))) + maybenewline + (strings.Repeat(" ", indent*plain)) + "]"
case builtinFunc: case builtinFunc:
if colored { if colored {
output = append(output, "\x1b[38;5;240m") output = append(output, "\x1b[38;240m")
} }
output = append(output, "<builtin function "+x.name+">") output = append(output, "<builtin function "+x.name+">")
if colored { if colored {
@@ -181,7 +181,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
} }
case Callable: case Callable:
if colored { if colored {
output = append(output, "\x1b[38;5;240m") output = append(output, "\x1b[38;240m")
} }
output = append(output, "<function "+x.name+">") output = append(output, "<function "+x.name+">")
if colored { if colored {

View File

@@ -11,105 +11,53 @@ type UNPARSEcode struct {
path string path string
} }
var knownFailures = map[string]ArErr{} var QuickKnownFailures = map[string]bool{}
func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine int) (any, bool, ArErr, int) { func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine int) (any, bool, ArErr, int) {
if knownErr, ok := knownFailures[code.code]; ok {
return nil, false, ArErr{
knownErr.TYPE,
knownErr.message,
code.line,
code.path,
code.realcode,
true,
}, 1
}
var ( var (
resp any = nil resp any = nil
worked bool = false worked bool = false
err ArErr = ArErr{"Syntax Error", "invalid syntax", code.line, code.path, code.realcode, true} err ArErr = ArErr{"Syntax Error", "invalid syntax", code.line, code.path, code.realcode, true}
i int = 1 i int = 1
) )
if isLine == 3 { if isLine >= 3 {
if isComment(code) { if isComment(code) {
resp, worked, err, i = parseComment(code, index, codelines) resp, worked, err, i = parseComment(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
} else if isIfStatement(code) {
resp, worked, err, i = parseIfStatement(code, index, codelines)
if !worked {
knownFailures[code.code] = err
} }
return resp, worked, err, i if isIfStatement(code) {
return parseIfStatement(code, index, codelines)
} else if isWhileLoop(code) { } else if isWhileLoop(code) {
resp, worked, err, i = parseWhileLoop(code, index, codelines) return parseWhileLoop(code, index, codelines)
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i
} else if isForeverLoop(code) { } else if isForeverLoop(code) {
resp, worked, err, i = parseForeverLoop(code, index, codelines) return parseForeverLoop(code, index, codelines)
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i
} else if isForLoop(code) { } else if isForLoop(code) {
resp, worked, err, i = parseForLoop(code, index, codelines) return parseForLoop(code, index, codelines)
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i
} else if isGenericImport(code) { } else if isGenericImport(code) {
resp, worked, err, i = parseGenericImport(code, index, codelines) return parseGenericImport(code, index, codelines)
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i
} else if isTryCatch(code) { } else if isTryCatch(code) {
resp, worked, err, i = parseTryCatch(code, index, codelines) return parseTryCatch(code, index, codelines)
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i
} }
} }
if isLine >= 2 { if isLine >= 2 {
if isReturn(code) { if isReturn(code) {
resp, worked, err, i = parseReturn(code, index, codelines) return parseReturn(code, index, codelines)
if !worked {
knownFailures[code.code] = err } else if isBreak(code) {
} return parseBreak(code)
return resp, worked, err, i
} else if isBreak(code) { } else if isContinue(code) {
resp, worked, err, i = parseBreak(code) return parseContinue(code)
if !worked {
knownFailures[code.code] = err } else if isDeleteVariable(code) {
} return parseDelete(code, index, codelines)
return resp, worked, err, i
} else if isContinue(code) {
resp, worked, err, i = parseContinue(code)
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i
} else if isDeleteVariable(code) {
resp, worked, err, i = parseDelete(code, index, codelines)
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i
}
}
if isLine >= 1 {
if isDoWrap(code) {
resp, worked, err, i = parseDoWrap(code, index, codelines)
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i
} }
} }
@@ -117,112 +65,100 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
isLine = 1 isLine = 1
} }
if isBoolean(code) { if isDoWrap(code) {
return parseDoWrap(code, index, codelines)
} else if isBoolean(code) {
return parseBoolean(code) return parseBoolean(code)
} else if isBrackets(code) { } else if !QuickKnownFailures["brackets"+code.code] && isBrackets(code) {
resp, worked, err, i = parseBrackets(code, index, codelines) resp, worked, err, i = parseBrackets(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
QuickKnownFailures["brackets"+code.code] = true
} }
if isAbs(code) { if !QuickKnownFailures["abs"+code.code] && isAbs(code) {
resp, worked, err, i = parseAbs(code, index, codelines) resp, worked, err, i = parseAbs(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
QuickKnownFailures["abs"+code.code] = true
} }
if isSetVariable(code) { if !QuickKnownFailures["autoasign"+code.code] && isAutoAsignVariable(code) {
resp, worked, err, i = parseSetVariable(code, index, codelines, isLine)
if worked {
return resp, worked, err, i
}
}
if isAutoAsignVariable(code) {
resp, worked, err, i = parseAutoAsignVariable(code, index, codelines, isLine) resp, worked, err, i = parseAutoAsignVariable(code, index, codelines, isLine)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
QuickKnownFailures["autoasign"+code.code] = true
} }
if isNumber(code) { if isSetVariable(code) {
resp, worked, err, i = parseNumber(code) return parseSetVariable(code, index, codelines, isLine)
if !worked { } else if isNumber(code) {
knownFailures[code.code] = err return parseNumber(code)
}
return resp, worked, err, i
} else if isString(code) { } else if isString(code) {
resp, worked, err, i = parseString(code) return parseString(code)
if !worked { } else if !QuickKnownFailures["squareroot"+code.code] && issquareroot(code) {
knownFailures[code.code] = err
}
return resp, worked, err, i
} else if issquareroot(code) {
resp, worked, err, i = parseSquareroot(code, index, codelines) resp, worked, err, i = parseSquareroot(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
QuickKnownFailures["squareroot"+code.code] = true
} }
if isFactorial(code) { if !QuickKnownFailures["factorial"+code.code] && isFactorial(code) {
resp, worked, err, i = parseFactorial(code, index, codelines) resp, worked, err, i = parseFactorial(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
QuickKnownFailures["factorial"+code.code] = true
} }
if isVariable(code) { if isVariable(code) {
resp, worked, err, i = parseVariable(code) return parseVariable(code)
if !worked {
knownFailures[code.code] = err
} }
return resp, worked, err, i if !QuickKnownFailures["array"+code.code] && isArray(code) {
}
if isArray(code) {
resp, worked, err, i = parseArray(code, index, codelines) resp, worked, err, i = parseArray(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
QuickKnownFailures["array"+code.code] = true
} else if isMap(code) { } else if isMap(code) {
resp, worked, err, i = parseMap(code, index, codelines) resp, worked, err, i = parseMap(code, index, codelines)
} }
if isnot(code) { if !QuickKnownFailures["not"+code.code] && isnot(code) {
resp, worked, err, i = parseNot(code, index, codelines, isLine) resp, worked, err, i = parseNot(code, index, codelines, isLine)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
QuickKnownFailures["not"+code.code] = true
} }
{ if !QuickKnownFailures["operations"+code.code] {
operation, worked, err, step := parseOperations(code, index, codelines) operation, worked, err, step := parseOperations(code, index, codelines)
if worked { if worked {
return operation, worked, err, step return operation, worked, err, step
} else if err.EXISTS { }
QuickKnownFailures["operations"+code.code] = true
if err.EXISTS {
return nil, worked, err, step return nil, worked, err, step
} }
} }
if isCall(code) { if isNegative(code) {
return parseNegative(code, index, codelines)
}
if !QuickKnownFailures["call"+code.code] && isCall(code) {
resp, worked, err, i = parseCall(code, index, codelines) resp, worked, err, i = parseCall(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
QuickKnownFailures["call"+code.code] = true
} }
if isNegative(code) { if isMapGet(code) {
resp, worked, err, i = parseNegative(code, index, codelines) return mapGetParse(code, index, codelines)
if !worked { } else if !QuickKnownFailures["indexget"+code.code] && isIndexGet(code) {
knownFailures[code.code] = err
}
return resp, worked, err, i
} else if isMapGet(code) {
resp, worked, err, i = mapGetParse(code, index, codelines)
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i
} else if isIndexGet(code) {
resp, worked, err, i = indexGetParse(code, index, codelines) resp, worked, err, i = indexGetParse(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
QuickKnownFailures["indexget"+code.code] = true
} }
if !worked {
knownFailures[code.code] = err
}
return resp, worked, err, i return resp, worked, err, i
} }
@@ -237,7 +173,7 @@ func translate(codelines []UNPARSEcode) ([]any, ArErr) {
if currentindent != 0 { if currentindent != 0 {
return nil, ArErr{"Syntax Error", "invalid indent", codelines[i].line, codelines[i].path, codelines[i].realcode, true} return nil, ArErr{"Syntax Error", "invalid indent", codelines[i].line, codelines[i].path, codelines[i].realcode, true}
} }
val, _, err, step := translateVal(codelines[i], i, codelines, 3) val, _, err, step := translateVal(codelines[i], i, codelines, 4)
i += step i += step
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err

View File

@@ -7,6 +7,18 @@ import (
var PIFloatInaccuracy number = newNumber() var PIFloatInaccuracy number = newNumber()
type sinCacheValue struct {
INPUT number
OUTPUT number
}
var sinCache = []sinCacheValue{
{newNumber(), newNumber()},
{newNumber().Quo(PI, newNumber().SetInt64(2)), newNumber().SetInt64(1)},
{PI, newNumber()},
{newNumber().Add(PI, newNumber().Quo(PI, newNumber().SetInt64(2))), newNumber().SetInt64(-1)},
}
func init() { func init() {
PIFloatInaccuracy.SetFloat64(math.Asin(1) * 2) PIFloatInaccuracy.SetFloat64(math.Asin(1) * 2)
} }
@@ -25,6 +37,18 @@ var ArSin = builtinFunc{"sin", func(args ...any) (any, ArErr) {
} }
} }
num := newNumber().Set(args[0].(number)) num := newNumber().Set(args[0].(number))
toTrim := newNumber().Mul(PI, newNumber().SetInt64(2))
toTrim.Quo(num, toTrim)
toTrim = floor(toTrim)
toTrim.Mul(toTrim, newNumber().Mul(PI, newNumber().SetInt64(2)))
num.Sub(num, toTrim)
for i := 0; i < len(sinCache); i++ {
if sinCache[i].INPUT.Cmp(num) == 0 {
return sinCache[i].OUTPUT, ArErr{}
}
}
num.Quo(num, PI) num.Quo(num, PI)
num.Mul(num, PIFloatInaccuracy) num.Mul(num, PIFloatInaccuracy)
n, _ := num.Float64() n, _ := num.Float64()
@@ -71,12 +95,7 @@ var ArCos = builtinFunc{"cos", func(args ...any) (any, ArErr) {
EXISTS: true, EXISTS: true,
} }
} }
num := newNumber().Set(args[0].(number)) return builtinCall(ArSin, []any{newNumber().Add(args[0].(number), newNumber().Quo(PI, newNumber().SetInt64(2)))})
num.Quo(num, PI)
num.Mul(num, PIFloatInaccuracy)
n, _ := num.Float64()
outputnum := newNumber().SetFloat64(math.Cos(n))
return outputnum, ArErr{}
}} }}
var ArArccos = builtinFunc{"arccos", func(args ...any) (any, ArErr) { var ArArccos = builtinFunc{"arccos", func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {

View File

@@ -23,7 +23,7 @@ func isTryCatch(code UNPARSEcode) bool {
func parseTryCatch(code UNPARSEcode, index int, codelines []UNPARSEcode) (TryCatch, bool, ArErr, int) { func parseTryCatch(code UNPARSEcode, index int, codelines []UNPARSEcode) (TryCatch, bool, ArErr, int) {
trytrimmed := strings.TrimSpace(code.code) trytrimmed := strings.TrimSpace(code.code)
totalIndex := 0 totalIndex := 0
tryparsed, worked, err, i := translateVal(UNPARSEcode{trytrimmed[4:], code.realcode, code.line, code.path}, index, codelines, 1) tryparsed, worked, err, i := translateVal(UNPARSEcode{trytrimmed[4:], code.realcode, code.line, code.path}, index, codelines, 3)
if !worked { if !worked {
return TryCatch{}, false, err, i return TryCatch{}, false, err, i
} }
@@ -40,7 +40,7 @@ func parseTryCatch(code UNPARSEcode, index int, codelines []UNPARSEcode) (TryCat
catchbracketSplit := strings.SplitN(catchtrimmed, ")", 2) catchbracketSplit := strings.SplitN(catchtrimmed, ")", 2)
errorName := strings.TrimSpace(strings.TrimSpace(catchbracketSplit[0])[1:]) errorName := strings.TrimSpace(strings.TrimSpace(catchbracketSplit[0])[1:])
errcode := catchbracketSplit[1] errcode := catchbracketSplit[1]
catchparsed, worked, err, i := translateVal(UNPARSEcode{errcode, code.realcode, code.line, code.path}, index+totalIndex, codelines, 1) catchparsed, worked, err, i := translateVal(UNPARSEcode{errcode, code.realcode, code.line, code.path}, index+totalIndex, codelines, 3)
if !worked { if !worked {
return TryCatch{}, false, err, i return TryCatch{}, false, err, i
} }

View File

@@ -60,7 +60,7 @@ func parseWhileLoop(code UNPARSEcode, index int, codeline []UNPARSEcode) (whileL
}, },
index+outindex-1, index+outindex-1,
codeline, codeline,
2, 3,
) )
if err.EXISTS || !worked { if err.EXISTS || !worked {
return whileLoop{}, worked, err, step return whileLoop{}, worked, err, step
@@ -96,7 +96,7 @@ func parseForeverLoop(code UNPARSEcode, index int, codeline []UNPARSEcode) (whil
}, },
index, index,
codeline, codeline,
2, 3,
) )
return whileLoop{ return whileLoop{
condition: true, condition: true,
@@ -108,13 +108,14 @@ func parseForeverLoop(code UNPARSEcode, index int, codeline []UNPARSEcode) (whil
} }
func runWhileLoop(loop whileLoop, stack stack, stacklevel int) (any, ArErr) { func runWhileLoop(loop whileLoop, stack stack, stacklevel int) (any, ArErr) {
newstack := append(stack, newscope()) newstack := append(stack, newscope())
for { for {
condition, err := runVal(loop.condition, newstack, stacklevel+1) condition, err := runVal(loop.condition, newstack, stacklevel+1)
newbodystack := append(newstack, newscope())
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
newbodystack := append(newstack, newscope())
if !anyToBool(condition) { if !anyToBool(condition) {
break break
} }

View File

@@ -1,33 +1,45 @@
let interpret(code) = do let brainfuck(INPUT) = do
memory = map() memory = [0] * 30*1000
pointer = 0 pointer = 0
code_ptr = 0 output = ""
loops = [] i = 0
while (i < INPUT.length) do
if (INPUT[i] == ">") do
pointer += 1
else if (INPUT[i] == "<") do
pointer -= 1
else if (INPUT[i] == "+") do
memory[pointer] += 1
else if (INPUT[i] == "-") do
memory[pointer] -= 1
else if (INPUT[i] == ".") do
output += chr(memory[pointer])
else if (INPUT[i] == ",") do
memory[pointer] = ord(input())
else if (INPUT[i] == "[") do
if (memory[pointer] == 0) do
count = 1
while (count > 0) do
i += 1
if (INPUT[i] == "[") do
count += 1
else if (INPUT[i] == "]") do
count -= 1
else if (INPUT[i] == "]") do
if (memory[pointer] != 0) do
count = 1
while (count > 0) do
i -= 1
if (INPUT[i] == "]") do
count += 1
else if (INPUT[i] == "[") do
count -= 1
else do
pass
i += 1
term.print(memory)
return output
while (code_ptr < code.length) do term.time("brainfuck")
command = code[code_ptr] term.plain.oneLine(brainfuck(input()))
term.timeEnd("brainfuck")
if (command == '>') pointer = pointer + 1
else if (command == '<') pointer = pointer - 1
else if (command == '+') do
if (pointer not in memory) memory[pointer] = 0
memory[pointer] = memory[pointer] + 1
else if (command == '-') do
if (pointer not in memory) memory[pointer] = 0
memory[pointer] = memory[pointer] - 1
else if (command == '.') term.log((memory.get(pointer, 0)))
else if (command == ',') memory[pointer] = ord(input())
else if (command == '[') do
if (memory.get(pointer, 0) == 0) do
loop_depth = 1
while (loop_depth > 0) do
code_ptr = code_ptr + 1
if (code[code_ptr] == '[') loop_depth = loop_depth + 1
else if (code[code_ptr] == ']') loop_depth = loop_depth - 1
else loops.append(code_ptr)
else if (command == ']') do
if (memory.get(pointer, 0) != 0) code_ptr = loops[-1]
else loops.pop()
code_ptr = code_ptr + 1
interpret('>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++.')

13
tests/broken_funcCall.ar Normal file
View File

@@ -0,0 +1,13 @@
let x = do
let class = {}
class.f(path) = do
let nice(callback) = do
callback()
return class
let class = {nice:nice}
return class
class.cool(path, callback) = class.f(path).nice(callback)
return class
term.log(x.cool("to", ()=term.log("epic")).nice(()=term.log("test")))

20
tests/chatbot code.ar Normal file
View File

@@ -0,0 +1,20 @@
# This is a comment
term.log("Hello World!") # Printing to console/output
value = "Hello" # Declaring a variable
do # Start of indented block
combined = value + " World!"
term.log(combined)
loop = true # Using true condition
while (loop) do # While loop syntax
term.log("Looping...")
loop = false # Using false condition
if (value == "Hello") do # If statement syntax
term.log("The value is Hello")
else do # else block
term.log("The value is not Hello")

2
tests/circular_import.ar Normal file
View File

@@ -0,0 +1,2 @@
import "circular_test"
term.log("epic wow")

2
tests/circular_test.ar Normal file
View File

@@ -0,0 +1,2 @@
import "circular_import"
term.log("hello")

View File

@@ -1,5 +1,5 @@
let zero = 1e-1000 let h = 1e-1000
let diff(f) = (x) = (f(x + zero) - f(x)) / zero let diff(f) = (x) = (f(x + h) - f(x)) / h
let f(x) = x^10+x^9+x^8+x^7+x^6+x^5+x^4+x^3+x^2+x+1 let f(x) = x^10+x^9+x^8+x^7+x^6+x^5+x^4+x^3+x^2+x+1

16
tests/multi_threading.ar Normal file
View File

@@ -0,0 +1,16 @@
let mythread(threadID) = do
term.log(threadID, "start")
let mynumber = 10
for (i from 0 to 1e4) do
mynumber += 1
mynumber
return term.log(threadID, "done")
let threads = []
term.time("start")
for (i from 0 to 100) do
threads.append(thread(()=mythread(i)))
threads[i].start()
for (i from 0 to 100) do
threads[i].join()
term.timeEnd("start")

2
tests/rng.ar Normal file
View File

@@ -0,0 +1,2 @@
forever do
term.log(random())

1
wasm-build Executable file
View File

@@ -0,0 +1 @@
GOOS=js GOARCH=wasm go build -trimpath -ldflags="-s -w" -o ./bin/argon.wasm ./src