mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
Compare commits
34 Commits
int64_impl
...
master-fai
| Author | SHA1 | Date | |
|---|---|---|---|
| 2543822418 | |||
| afbf868703 | |||
|
|
1c048579a5 | ||
| 199b2320dd | |||
| 857eb442c2 | |||
|
|
5ceff0ddd2 | ||
| 2d3c7c42ce | |||
| 90b506d22f | |||
| f9777611dd | |||
| bc3e50697f | |||
| 6226cc52ac | |||
| c881d06cb5 | |||
| 584841030c | |||
| 58c57f154b | |||
| c698b878da | |||
| 280635d46e | |||
| e05267c886 | |||
| 4c412a763a | |||
| de95c3e8b5 | |||
| d0d73db6cf | |||
| aea3b73e71 | |||
|
|
e06d28ca02 | ||
| bf145db749 | |||
| 0514783230 | |||
| 7ef9384d76 | |||
| 957029ebd4 | |||
| afc5ae2086 | |||
| a6c14b49a5 | |||
| 1e625a589a | |||
| 5e65ff01ac | |||
| 5e48a70c77 | |||
|
|
69faa23ea9 | ||
|
|
126d287611 | ||
| 97ec428aca |
24
.github/workflows/build_release.yml
vendored
24
.github/workflows/build_release.yml
vendored
@@ -1,24 +0,0 @@
|
|||||||
# 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'
|
|
||||||
32
.github/workflows/go.yml
vendored
32
.github/workflows/go.yml
vendored
@@ -1,32 +0,0 @@
|
|||||||
# This workflow will build a golang project
|
|
||||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
|
|
||||||
|
|
||||||
name: Go
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Install or Update CA Certificates
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y --reinstall ca-certificates
|
|
||||||
|
|
||||||
- name: Set up Go
|
|
||||||
uses: actions/setup-go@v4
|
|
||||||
with:
|
|
||||||
go-version: '1.20'
|
|
||||||
- name: Build
|
|
||||||
run: ./build
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: go test -v ./src
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,2 @@
|
|||||||
bin
|
bin
|
||||||
array.json
|
array.json
|
||||||
argon_modules
|
|
||||||
.DS_Store
|
|
||||||
29
Dockerfile
29
Dockerfile
@@ -1,29 +0,0 @@
|
|||||||
# Use Alpine as the base image
|
|
||||||
FROM golang:alpine
|
|
||||||
|
|
||||||
# Install isotope
|
|
||||||
FROM ugric/isotope:latest
|
|
||||||
|
|
||||||
# Set the Current Working Directory inside the container
|
|
||||||
WORKDIR /argon
|
|
||||||
|
|
||||||
# Copy go mod and sum files
|
|
||||||
COPY go.mod go.sum ./
|
|
||||||
|
|
||||||
# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
|
|
||||||
RUN go mod download
|
|
||||||
|
|
||||||
# Copy the source from the current directory to the Working Directory inside the container
|
|
||||||
COPY ./src ./src
|
|
||||||
|
|
||||||
# Copy License
|
|
||||||
COPY LICENSE .
|
|
||||||
|
|
||||||
# Build the Go app
|
|
||||||
RUN go build -trimpath -ldflags="-s -w" -o bin/argon ./src
|
|
||||||
|
|
||||||
# make the binary executable
|
|
||||||
RUN chmod +x bin/argon
|
|
||||||
|
|
||||||
# add the binary to the path
|
|
||||||
ENV PATH="/argon/bin:${PATH}"
|
|
||||||
674
LICENSE
674
LICENSE
@@ -1,674 +0,0 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains free
|
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
|
||||||
any other work released this way by its authors. You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
||||||
46
app.py
Normal file
46
app.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
def interpret(code):
|
||||||
|
memory = {}
|
||||||
|
pointer = 0
|
||||||
|
code_ptr = 0
|
||||||
|
loops = []
|
||||||
|
|
||||||
|
while code_ptr < len(code):
|
||||||
|
command = code[code_ptr]
|
||||||
|
|
||||||
|
if command == '>':
|
||||||
|
pointer += 1
|
||||||
|
elif command == '<':
|
||||||
|
pointer -= 1
|
||||||
|
elif command == '+':
|
||||||
|
if pointer not in memory:
|
||||||
|
memory[pointer] = 0
|
||||||
|
memory[pointer] += 1
|
||||||
|
elif command == '-':
|
||||||
|
if pointer not in memory:
|
||||||
|
memory[pointer] = 0
|
||||||
|
memory[pointer] -= 1
|
||||||
|
elif command == '.':
|
||||||
|
print(chr(memory.get(pointer, 0)), end='')
|
||||||
|
elif command == ',':
|
||||||
|
memory[pointer] = ord(input())
|
||||||
|
elif command == '[':
|
||||||
|
if memory.get(pointer, 0) == 0:
|
||||||
|
loop_depth = 1
|
||||||
|
while loop_depth > 0:
|
||||||
|
code_ptr += 1
|
||||||
|
if code[code_ptr] == '[':
|
||||||
|
loop_depth += 1
|
||||||
|
elif code[code_ptr] == ']':
|
||||||
|
loop_depth -= 1
|
||||||
|
else:
|
||||||
|
loops.append(code_ptr)
|
||||||
|
elif command == ']':
|
||||||
|
if memory.get(pointer, 0) != 0:
|
||||||
|
code_ptr = loops[-1]
|
||||||
|
else:
|
||||||
|
loops.pop()
|
||||||
|
code_ptr += 1
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
interpret("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.")
|
||||||
|
# Output: Hello World!
|
||||||
2
build
2
build
@@ -1 +1 @@
|
|||||||
go build -trimpath -ldflags="-s -w" -o bin/argon ./src
|
GOOS=js GOARCH=wasm go build -o wasm/bin/argon.wasm ./src
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
@echo off
|
@echo off
|
||||||
go build -trimpath -ldflags="-s -w" -o bin/argon.exe ./src
|
set GOOS=js
|
||||||
|
set GOARCH=wasm
|
||||||
|
go build -o wasm/bin/argon.wasm ./src
|
||||||
2
debug
2
debug
@@ -1,2 +0,0 @@
|
|||||||
# 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
|
|
||||||
__ARGON_DEBUG__=true go run ./src "$@"
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
:: 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
|
|
||||||
go run ./src %*
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
@echo off
|
|
||||||
go build -o bin/debug_argon.exe ./src
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
docker build -t ugric/argon .
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
docker push ugric/argon
|
|
||||||
10
go.mod
10
go.mod
@@ -7,16 +7,6 @@ require (
|
|||||||
github.com/wadey/go-rounding v1.1.0
|
github.com/wadey/go-rounding v1.1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/chzyer/readline v1.5.1 // indirect
|
|
||||||
github.com/joho/godotenv v1.5.1 // indirect
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2
|
|
||||||
golang.org/x/net v0.8.0 // indirect
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
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
|
||||||
|
|||||||
9
go.sum
9
go.sum
@@ -1,13 +1,5 @@
|
|||||||
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/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
|
||||||
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=
|
||||||
github.com/jwalton/go-supportscolor v1.1.0/go.mod h1:hFVUAZV2cWg+WFFC4v8pT2X/S2qUUBYMioBD9AINXGs=
|
github.com/jwalton/go-supportscolor v1.1.0/go.mod h1:hFVUAZV2cWg+WFFC4v8pT2X/S2qUUBYMioBD9AINXGs=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
@@ -23,7 +15,6 @@ 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-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=
|
||||||
|
|||||||
21
licence
Normal file
21
licence
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Open Argon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
2
merge
Executable file
2
merge
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
git fetch upstream
|
||||||
|
git merge upstream/master master
|
||||||
2
merge.bat
Normal file
2
merge.bat
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
git fetch upstream
|
||||||
|
git merge upstream/master master
|
||||||
27
modules/csv/init.ar
Normal file
27
modules/csv/init.ar
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
let read(path) = do
|
||||||
|
f = file.read(path)
|
||||||
|
text = f.text()
|
||||||
|
data = []
|
||||||
|
splitlines = text.split("\n")
|
||||||
|
for (i from 0 to splitlines.length) do
|
||||||
|
values = []
|
||||||
|
in_quotes = false
|
||||||
|
start = 0
|
||||||
|
line = splitlines[i]
|
||||||
|
for (j from 0 to line.length) do
|
||||||
|
char = line[j]
|
||||||
|
if (char == "," && not in_quotes) do
|
||||||
|
value = line[start:j].rightstrip("\r").strip()
|
||||||
|
if (value && value[0] == "\"" && value[-1] == "\"") value = value[1:value.length - 1]
|
||||||
|
value = value.replace("\"\"", "\"")
|
||||||
|
values.append(value)
|
||||||
|
start = j + 1
|
||||||
|
else if (char == "\"") in_quotes = not in_quotes
|
||||||
|
if (j == line.length - 1) do
|
||||||
|
value = line[start:j + 1].rightstrip("\r").strip()
|
||||||
|
if (value && value[0] == "\"" && value[-1] == "\"") value = value[1:value.length - 1]
|
||||||
|
value = value.replace("\"\"", "\"")
|
||||||
|
values.append(value)
|
||||||
|
data.append(values)
|
||||||
|
|
||||||
|
return data
|
||||||
53
modules/this.ar
Normal file
53
modules/this.ar
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# The Argon Manifesto - ChatGPT
|
||||||
|
|
||||||
|
# Simple is better than complex
|
||||||
|
# Argon's design, we should respect
|
||||||
|
# Readability is key, it's plain to see
|
||||||
|
# With Argon, code clarity comes naturally
|
||||||
|
|
||||||
|
# Sparse is better than dense
|
||||||
|
# Argon's syntax, it makes sense
|
||||||
|
# No need for excess, or verbosity
|
||||||
|
# With Argon, brevity is a necessity
|
||||||
|
|
||||||
|
# Explicit is better than implicit
|
||||||
|
# Argon's logic, it's not cryptic
|
||||||
|
# Avoiding confusion, it's a must
|
||||||
|
# With Argon, understanding is a trust
|
||||||
|
|
||||||
|
# Errors should never pass silently
|
||||||
|
# Argon catches them, and does so quietly
|
||||||
|
# Graceful handling, it's what we aim to achieve
|
||||||
|
# With Argon, bugs are easier to perceive
|
||||||
|
|
||||||
|
# That which is complex, can be made simple
|
||||||
|
# Argon's power, it's in its example
|
||||||
|
# Programming, it can be a breeze
|
||||||
|
# With Argon, it's a language that's sure to please
|
||||||
|
|
||||||
|
term.log("The Argon Manifesto - ChatGPT")
|
||||||
|
term.log()
|
||||||
|
term.log("Simple is better than complex")
|
||||||
|
term.log("Argon's design, we should respect")
|
||||||
|
term.log("Readability is key, it's plain to see")
|
||||||
|
term.log("With Argon, code clarity comes naturally")
|
||||||
|
term.log()
|
||||||
|
term.log("Sparse is better than dense")
|
||||||
|
term.log("Argon's syntax, it makes sense")
|
||||||
|
term.log("No need for excess, or verbosity")
|
||||||
|
term.log("With Argon, brevity is a necessity")
|
||||||
|
term.log()
|
||||||
|
term.log("Explicit is better than implicit")
|
||||||
|
term.log("Argon's logic, it's not cryptic")
|
||||||
|
term.log("Avoiding confusion, it's a must")
|
||||||
|
term.log("With Argon, understanding is a trust")
|
||||||
|
term.log()
|
||||||
|
term.log("Errors should never pass silently")
|
||||||
|
term.log("Argon catches them, and does so quietly")
|
||||||
|
term.log("Graceful handling, it's what we aim to achieve")
|
||||||
|
term.log("With Argon, bugs are easier to perceive")
|
||||||
|
term.log()
|
||||||
|
term.log("That which is complex, can be made simple")
|
||||||
|
term.log("Argon's power, it's in its example")
|
||||||
|
term.log("Programming, it can be a breeze")
|
||||||
|
term.log("With Argon, it's a language that's sure to please")
|
||||||
25
readme.md
25
readme.md
@@ -2,24 +2,37 @@
|
|||||||
<p>
|
<p>
|
||||||
<img width="150" src="logos/ArLogo.png">
|
<img width="150" src="logos/ArLogo.png">
|
||||||
</p>
|
</p>
|
||||||
<h1>Argon v3</h1>
|
<h1>Argon v3.wasm</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
[](https://github.com/Open-Argon/argon-v3/actions/workflows/go.yml)
|
### HEADS UP! 🙂
|
||||||
|
|
||||||
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.
|
Argon v3.wasm is a fork of Argon v3 which has had parts rewritten for support in WebAssembly (WASM).
|
||||||
|
|
||||||
|
It includes all the same features and functionality as Argon v3, but has been compiled to run efficiently on WebAssembly.
|
||||||
|
|
||||||
|
Please note that Argon v3.wasm can only be compiled for use with WebAssembly.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
## 📚 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.
|
||||||
- All numbers are stored as rational numbers, preventing precision errors.
|
- All numbers are stored as rational numbers, preventing precision errors.
|
||||||
- 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)`.
|
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)`.
|
||||||
|
|
||||||
## 📖 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:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -28,7 +41,7 @@ argon example.ar
|
|||||||
|
|
||||||
## 🔍 Specification
|
## 🔍 Specification
|
||||||
|
|
||||||
For a detailed specification of the Argon 3 language, please refer to [the docs](https://argon.wbell.dev/docs/).
|
For a detailed specification of the Argon 3 language, please refer to [spec.md](spec.md).
|
||||||
|
|
||||||
## 🚀 Example Code
|
## 🚀 Example Code
|
||||||
|
|
||||||
@@ -39,10 +52,10 @@ f(x) = x^2 + 2*x + 1
|
|||||||
term.log('f(10) =', f(10))
|
term.log('f(10) =', f(10))
|
||||||
```
|
```
|
||||||
|
|
||||||
This code defines a function f(x) that calculates x^2 + 2*x + 1. It then calls the function with an argument of 10 and logs the result to the console.
|
This code defines a function f(x) that calculates x^2 + 2\*x + 1. It then calls the function with an argument of 10 and logs the result to the console.
|
||||||
|
|
||||||
Please note that this example is subject to change as the specification is in beta and may be updated frequently.
|
Please note that this example is subject to change as the specification is in beta and may be updated frequently.
|
||||||
|
|
||||||
## Licence
|
## Licence
|
||||||
|
|
||||||
GNU General Public License v3.0
|
MIT
|
||||||
|
|||||||
2
run
2
run
@@ -1,2 +0,0 @@
|
|||||||
# 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
|
|
||||||
go run ./src "$@"
|
|
||||||
5
run.bat
5
run.bat
@@ -1,5 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
:: 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
|
|
||||||
|
|
||||||
go run ./src %*
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import "http.ar" as http
|
|
||||||
|
|
||||||
let server = http.server()
|
|
||||||
|
|
||||||
let home(req,res) = do
|
|
||||||
res.send("hello world")
|
|
||||||
server.get("/",home)
|
|
||||||
|
|
||||||
server.run()
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "server-test",
|
|
||||||
"version": "1.0.0"
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[{"Name":"http.ar","Version":"1.1.6","URL":"https://isotope.wbell.dev/isotope-download?name=http.ar\u0026version=1.1.6","Remote":"isotope.wbell.dev"}]
|
|
||||||
46
src/abs.go
46
src/abs.go
@@ -40,28 +40,38 @@ func parseAbs(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runAbs(x ABS, stack stack, stacklevel int) (any, ArErr) {
|
func runAbs(x ABS, stack stack, stacklevel int) (any, ArErr) {
|
||||||
value, err := runVal(x, stack, stacklevel+1)
|
resp, err := runVal(x.body, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
switch value := value.(type) {
|
if typeof(resp) != "number" {
|
||||||
case ArObject:
|
return nil, ArErr{TYPE: "Runtime Error",
|
||||||
if Callable, ok := value.obj["__abs__"]; ok {
|
message: fmt.Sprintf("abs expected number, got %s", typeof(resp)),
|
||||||
return runCall(call{
|
EXISTS: true,
|
||||||
Callable: Callable,
|
|
||||||
Args: []any{},
|
|
||||||
Code: x.code,
|
|
||||||
Line: x.line,
|
|
||||||
Path: x.path,
|
|
||||||
}, stack, stacklevel)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{
|
return abs(resp.(number)), ArErr{}
|
||||||
"TypeError",
|
}
|
||||||
fmt.Sprint("abs() not supported on ", typeof(value)),
|
|
||||||
x.line,
|
func abs(x number) number {
|
||||||
x.path,
|
if x.Sign() < 0 {
|
||||||
x.code,
|
return x.Neg(x)
|
||||||
true,
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArAbs = builtinFunc{"abs", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return nil, ArErr{TYPE: "Runtime Error",
|
||||||
|
message: fmt.Sprintf("abs expected 1 argument, got %d", len(args)),
|
||||||
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if typeof(args[0]) != "number" {
|
||||||
|
return nil, ArErr{TYPE: "Runtime Error",
|
||||||
|
message: fmt.Sprintf("abs expected number, got %s", typeof(args[0])),
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return abs(args[0].(number)), ArErr{}
|
||||||
|
}}
|
||||||
|
|||||||
208
src/array.go
208
src/array.go
@@ -23,48 +23,7 @@ func ArArray(arr []any) ArObject {
|
|||||||
anymap{
|
anymap{
|
||||||
"__name__": "array",
|
"__name__": "array",
|
||||||
"__value__": arr,
|
"__value__": arr,
|
||||||
},
|
"length": newNumber().SetUint64(uint64(len(arr))),
|
||||||
}
|
|
||||||
val.obj["__json__"] = builtinFunc{
|
|
||||||
"__json__",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return "", ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typeof(args[0]) != "number" {
|
|
||||||
return "", ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected number, got " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output := []string{}
|
|
||||||
|
|
||||||
level, err := numberToInt64(args[0].(ArObject))
|
|
||||||
if err != nil {
|
|
||||||
return "", ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, value := range arr {
|
|
||||||
str, err := jsonstringify(value, level+1)
|
|
||||||
if err != nil {
|
|
||||||
return "", ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output = append(output, str)
|
|
||||||
}
|
|
||||||
return "[" + strings.Join(output, ", ") + "]", ArErr{}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
val.obj["__setindex__"] = builtinFunc{
|
val.obj["__setindex__"] = builtinFunc{
|
||||||
@@ -80,26 +39,18 @@ func ArArray(arr []any) ArObject {
|
|||||||
if typeof(a[0]) != "number" {
|
if typeof(a[0]) != "number" {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "TypeError",
|
TYPE: "TypeError",
|
||||||
message: "index must be a number",
|
message: "dex must be a number",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isNumberInt(a[0].(ArObject)) {
|
if !a[0].(number).IsInt() {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "TypeError",
|
TYPE: "TypeError",
|
||||||
message: "index must be an integer",
|
message: "index must be an integer",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
num64, err := numberToInt64(a[0].(ArObject))
|
num := int(a[0].(number).Num().Int64())
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num := int(num64)
|
|
||||||
if num < 0 || num >= len(arr) {
|
if num < 0 || num >= len(arr) {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "IndexError",
|
TYPE: "IndexError",
|
||||||
@@ -117,19 +68,9 @@ func ArArray(arr []any) 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 || len(a) == 0 {
|
if len(a) > 3 {
|
||||||
return nil, ArErr{"TypeError", "expected 1 to 3 arguments, got " + fmt.Sprint(len(a)), 0, "", "", true}
|
return nil, ArErr{"TypeError", "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 Number(len(arr)), ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var (
|
var (
|
||||||
start int = 0
|
start int = 0
|
||||||
end any = nil
|
end any = nil
|
||||||
@@ -138,67 +79,42 @@ func ArArray(arr []any) ArObject {
|
|||||||
{
|
{
|
||||||
if a[0] == nil {
|
if a[0] == nil {
|
||||||
start = 0
|
start = 0
|
||||||
} else if typeof(a[0]) != "number" || !isNumberInt(a[0].(ArObject)) {
|
} else if typeof(a[0]) != "number" || !a[0].(number).IsInt() {
|
||||||
return "", ArErr{
|
return "", ArErr{
|
||||||
TYPE: "TypeError",
|
TYPE: "TypeError",
|
||||||
message: "slice index must be an integer",
|
message: "slice index must be an integer",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
start64, err := numberToInt64(a[0].(ArObject))
|
start = int(a[0].(number).Num().Int64())
|
||||||
if err != nil {
|
|
||||||
return "", ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
start = int(start64)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(a) > 1 {
|
if len(a) > 1 {
|
||||||
if a[1] == nil {
|
if a[1] == nil {
|
||||||
end = len(arr)
|
end = len(arr)
|
||||||
} else if typeof(a[1]) != "number" || !isNumberInt(a[1].(ArObject)) {
|
} else if typeof(a[1]) != "number" || !a[1].(number).IsInt() {
|
||||||
return "", ArErr{
|
return "", ArErr{
|
||||||
TYPE: "TypeError",
|
TYPE: "TypeError",
|
||||||
message: "slice index must be an integer",
|
message: "slice index must be an integer",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
end64, err := numberToInt64(a[1].(ArObject))
|
end = int(a[1].(number).Num().Int64())
|
||||||
if err != nil {
|
|
||||||
return "", ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end = int(end64)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(a) > 2 {
|
if len(a) > 2 {
|
||||||
if a[2] == nil {
|
if a[2] == nil {
|
||||||
step = 1
|
step = 1
|
||||||
} else if typeof(a[2]) != "number" || !isNumberInt(a[2].(ArObject)) {
|
} else if typeof(a[2]) != "number" || !a[2].(number).IsInt() {
|
||||||
return "", ArErr{
|
return "", ArErr{
|
||||||
TYPE: "TypeError",
|
TYPE: "TypeError",
|
||||||
message: "slice index must be an integer",
|
message: "slice index must be an integer",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
step64, err := numberToInt64(a[2].(ArObject))
|
step = int(a[2].(number).Num().Int64())
|
||||||
if err != nil {
|
|
||||||
return "", ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
step = int(step64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var ogStart = start
|
|
||||||
if start < 0 {
|
if start < 0 {
|
||||||
start = len(arr) + start
|
start = len(arr) + start
|
||||||
}
|
}
|
||||||
@@ -208,13 +124,6 @@ func ArArray(arr []any) ArObject {
|
|||||||
if end != nil && end.(int) > len(arr) {
|
if end != nil && end.(int) > len(arr) {
|
||||||
end = len(arr)
|
end = len(arr)
|
||||||
}
|
}
|
||||||
if start >= len(arr) || start < 0 {
|
|
||||||
return "", ArErr{
|
|
||||||
TYPE: "Index Error",
|
|
||||||
message: "index out of range, trying to access index " + fmt.Sprint(ogStart) + " in array of length " + fmt.Sprint(len(arr)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if end == nil {
|
if end == nil {
|
||||||
return arr[start], ArErr{}
|
return arr[start], ArErr{}
|
||||||
} else if step == 1 {
|
} else if step == 1 {
|
||||||
@@ -250,22 +159,14 @@ func ArArray(arr []any) ArObject {
|
|||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isNumberInt(args[0].(ArObject)) {
|
if !args[0].(number).IsInt() {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "TypeError",
|
TYPE: "TypeError",
|
||||||
message: "argument must be an integer",
|
message: "argument must be an integer",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
num64, err := (numberToInt64(args[0].(ArObject)))
|
num := int(args[0].(number).Num().Int64())
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num := int(num64)
|
|
||||||
if num < 0 || num >= len(arr) {
|
if num < 0 || num >= len(arr) {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "IndexError",
|
TYPE: "IndexError",
|
||||||
@@ -274,6 +175,7 @@ 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{}
|
||||||
}}
|
}}
|
||||||
@@ -288,6 +190,7 @@ 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{}
|
||||||
},
|
},
|
||||||
@@ -309,22 +212,14 @@ func ArArray(arr []any) ArObject {
|
|||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isNumberInt(args[0].(ArObject)) {
|
if !args[0].(number).IsInt() {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "TypeError",
|
TYPE: "TypeError",
|
||||||
message: "argument must be an integer",
|
message: "argument must be an integer",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
num64, err := numberToInt64(args[0].(ArObject))
|
num := int(args[0].(number).Num().Int64())
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num := int(num64)
|
|
||||||
if num < 0 || num > len(arr) {
|
if num < 0 || num > len(arr) {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "IndexError",
|
TYPE: "IndexError",
|
||||||
@@ -333,6 +228,7 @@ 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{}
|
||||||
},
|
},
|
||||||
@@ -355,22 +251,14 @@ func ArArray(arr []any) ArObject {
|
|||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isNumberInt(args[0].(ArObject)) {
|
if !args[0].(number).IsInt() {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "TypeError",
|
TYPE: "TypeError",
|
||||||
message: "argument must be an integer",
|
message: "argument must be an integer",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
num64, err := (numberToInt64(args[0].(ArObject)))
|
num := int(args[0].(number).Num().Int64())
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num := int(num64)
|
|
||||||
if num < 0 || num >= len(arr) {
|
if num < 0 || num >= len(arr) {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "IndexError",
|
TYPE: "IndexError",
|
||||||
@@ -380,11 +268,13 @@ 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{}
|
||||||
},
|
},
|
||||||
@@ -400,6 +290,7 @@ 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{}
|
||||||
},
|
},
|
||||||
@@ -422,6 +313,7 @@ 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"] = len(arr)
|
||||||
val.obj["__value__"] = arr
|
val.obj["__value__"] = arr
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
},
|
},
|
||||||
@@ -464,12 +356,8 @@ func ArArray(arr []any) ArObject {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if reverse {
|
|
||||||
for i, j := 0, len(output)-1; i < j; i, j = i+1, j-1 {
|
|
||||||
output[i], output[j] = output[j], output[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arr = output
|
arr = output
|
||||||
|
val.obj["length"] = len(arr)
|
||||||
val.obj["__value__"] = arr
|
val.obj["__value__"] = arr
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}
|
}
|
||||||
@@ -485,6 +373,7 @@ func ArArray(arr []any) ArObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
arr = output
|
arr = output
|
||||||
|
val.obj["length"] = len(arr)
|
||||||
val.obj["__value__"] = arr
|
val.obj["__value__"] = arr
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
},
|
},
|
||||||
@@ -644,7 +533,7 @@ func ArArray(arr []any) ArObject {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
val.obj["__Equal__"] = builtinFunc{
|
val.obj["__Equal__"] = builtinFunc{
|
||||||
"__Equal__",
|
"__LessThanEqual__",
|
||||||
func(args ...any) (any, ArErr) {
|
func(args ...any) (any, ArErr) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
@@ -685,7 +574,7 @@ func ArArray(arr []any) ArObject {
|
|||||||
}
|
}
|
||||||
for _, v := range arr {
|
for _, v := range arr {
|
||||||
res, err := runOperation(operationType{
|
res, err := runOperation(operationType{
|
||||||
operation: 9,
|
operation: 8,
|
||||||
values: []any{v, args[0]},
|
values: []any{v, args[0]},
|
||||||
}, stack{}, 0)
|
}, stack{}, 0)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
@@ -698,47 +587,6 @@ func ArArray(arr []any) ArObject {
|
|||||||
return false, ArErr{}
|
return false, ArErr{}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
val.obj["__NotContains__"] = builtinFunc{
|
|
||||||
"__NotContains__",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "missing argument",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, v := range arr {
|
|
||||||
res, err := runOperation(operationType{
|
|
||||||
operation: 9,
|
|
||||||
values: []any{v, args[0]},
|
|
||||||
}, stack{}, 0)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if anyToBool(res) {
|
|
||||||
return false, ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
val.obj["copy"] = builtinFunc{
|
|
||||||
"copy",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
arrCopy := make([]any, len(arr))
|
|
||||||
copy(arrCopy, arr)
|
|
||||||
return ArArray(arrCopy), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
val.obj["__Boolean__"] = builtinFunc{
|
|
||||||
"__Boolean__",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
return len(
|
|
||||||
arr,
|
|
||||||
) > 0, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "math/big"
|
|
||||||
|
|
||||||
func AnyToArValid(arr any) any {
|
func AnyToArValid(arr any) any {
|
||||||
switch arr := arr.(type) {
|
switch arr := arr.(type) {
|
||||||
case []any:
|
case []any:
|
||||||
@@ -10,12 +8,6 @@ func AnyToArValid(arr any) any {
|
|||||||
return ArString(arr)
|
return ArString(arr)
|
||||||
case anymap:
|
case anymap:
|
||||||
return Map(arr)
|
return Map(arr)
|
||||||
case []byte:
|
|
||||||
return ArBuffer(arr)
|
|
||||||
case byte:
|
|
||||||
return ArByte(arr)
|
|
||||||
case int, int64, float64, float32, *big.Rat, *big.Int:
|
|
||||||
return Number(arr)
|
|
||||||
default:
|
default:
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,22 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "strings"
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func anyToBool(x any) bool {
|
func anyToBool(x any) bool {
|
||||||
switch x := x.(type) {
|
switch x := x.(type) {
|
||||||
case string:
|
case string:
|
||||||
return x != ""
|
return x != ""
|
||||||
|
case number:
|
||||||
|
return x.Cmp(newNumber()) != 0
|
||||||
case bool:
|
case bool:
|
||||||
return x
|
return x
|
||||||
case nil:
|
case nil:
|
||||||
return false
|
return false
|
||||||
case ArObject:
|
case ArObject:
|
||||||
if y, ok := x.obj["__Boolean__"]; ok {
|
if typeof(x) == "array" {
|
||||||
val, err := runCall(
|
return len(x.obj["__value__"].([]any)) != 0
|
||||||
call{
|
|
||||||
Callable: y,
|
|
||||||
Args: []any{},
|
|
||||||
}, stack{}, 0)
|
|
||||||
if err.EXISTS {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
return anyToBool(val)
|
return len(x.obj) != 0
|
||||||
}
|
|
||||||
return false
|
|
||||||
case builtinFunc:
|
case builtinFunc:
|
||||||
return true
|
return true
|
||||||
case Callable:
|
case Callable:
|
||||||
|
|||||||
@@ -6,11 +6,18 @@ 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) (any, bool, ArErr, int) {
|
func parseBrackets(code UNPARSEcode, index int, codeline []UNPARSEcode) (brackets, 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],
|
||||||
@@ -18,5 +25,10 @@ func parseBrackets(code UNPARSEcode, index int, codeline []UNPARSEcode) (any, bo
|
|||||||
line: code.line,
|
line: code.line,
|
||||||
path: code.path,
|
path: code.path,
|
||||||
}, index, codeline, 0)
|
}, index, codeline, 0)
|
||||||
return resp, worked, err, i
|
return brackets{
|
||||||
|
VAL: resp,
|
||||||
|
line: code.line,
|
||||||
|
code: code.realcode,
|
||||||
|
path: code.path,
|
||||||
|
}, worked, err, i
|
||||||
}
|
}
|
||||||
|
|||||||
543
src/buffer.go
543
src/buffer.go
@@ -1,543 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ArByte(Byte byte) ArObject {
|
|
||||||
obj := ArObject{
|
|
||||||
obj: anymap{
|
|
||||||
"__name__": "byte",
|
|
||||||
"__value__": Byte,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["__string__"] = builtinFunc{
|
|
||||||
"__string__",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
return ArString("0x" + hex.EncodeToString([]byte{Byte})), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["__repr__"] = builtinFunc{
|
|
||||||
"__repr__",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
return ArString("<byte 0x" + hex.EncodeToString([]byte{Byte}) + ">"), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["number"] = builtinFunc{
|
|
||||||
"number",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
return Number(int64(Byte)), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["from"] = builtinFunc{
|
|
||||||
"from",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) == 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected at least 1 argument, got 0",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
|
||||||
case int64:
|
|
||||||
if x > 255 || x < 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "ValueError",
|
|
||||||
message: "expected number between 0 and 255, got " + fmt.Sprint(x),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Byte = byte(x)
|
|
||||||
case string:
|
|
||||||
if len(x) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "ValueError",
|
|
||||||
message: "expected string of length 1, got " + fmt.Sprint(len(x)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Byte = byte(x[0])
|
|
||||||
default:
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected number or string, got " + typeof(x),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
|
|
||||||
func ArBuffer(buf []byte) ArObject {
|
|
||||||
obj := ArObject{
|
|
||||||
obj: anymap{
|
|
||||||
"__name__": "buffer",
|
|
||||||
"__value__": buf,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["__string__"] = builtinFunc{
|
|
||||||
"__string__",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
return ArString("<buffer length=" + fmt.Sprint(len(buf)) + ">"), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["__repr__"] = builtinFunc{
|
|
||||||
"__repr__",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
return ArString("<buffer length=" + fmt.Sprint(len(buf)) + ">"), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["from"] = builtinFunc{
|
|
||||||
"from",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) == 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected at least 1 argument, got 0",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
|
||||||
case string:
|
|
||||||
buf = []byte(x)
|
|
||||||
case []byte:
|
|
||||||
buf = x
|
|
||||||
case []any:
|
|
||||||
outputbuf := []byte{}
|
|
||||||
for _, v := range x {
|
|
||||||
V := ArValidToAny(v)
|
|
||||||
switch y := V.(type) {
|
|
||||||
case int64:
|
|
||||||
if y > 255 || y < 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "ValueError",
|
|
||||||
message: "expected number between 0 and 255, got " + fmt.Sprint(y),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outputbuf = append(outputbuf, byte(y))
|
|
||||||
default:
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "Cannot convert " + typeof(v) + " to byte",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf = outputbuf
|
|
||||||
default:
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected string or buffer, got " + typeof(x),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
obj.obj["__value__"] = buf
|
|
||||||
return obj, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["splitN"] = builtinFunc{
|
|
||||||
"splitN",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 2 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 1 argument, got " + fmt.Sprint(len(a)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
splitVal := ArValidToAny(a[0])
|
|
||||||
if typeof(splitVal) != "buffer" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected buffer, got " + typeof(splitVal),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var separator = splitVal.([]byte)
|
|
||||||
nVal := ArValidToAny(a[1])
|
|
||||||
if typeof(nVal) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected number, got " + typeof(nVal),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n, err := numberToInt64(nVal.(ArObject))
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var result [][]byte
|
|
||||||
start := 0
|
|
||||||
var i int64
|
|
||||||
for i = 0; i < n; i++ {
|
|
||||||
index := bytes.Index(buf[start:], separator)
|
|
||||||
if index == -1 {
|
|
||||||
result = append(result, buf[start:])
|
|
||||||
break
|
|
||||||
}
|
|
||||||
end := start + index
|
|
||||||
result = append(result, buf[start:end])
|
|
||||||
start = end + len(separator)
|
|
||||||
}
|
|
||||||
|
|
||||||
if int64(len(result)) != n {
|
|
||||||
result = append(result, buf[start:])
|
|
||||||
}
|
|
||||||
var bufoutput = []any{}
|
|
||||||
for _, v := range result {
|
|
||||||
bufoutput = append(bufoutput, ArBuffer(v))
|
|
||||||
}
|
|
||||||
return ArArray(bufoutput), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["split"] = builtinFunc{
|
|
||||||
"split",
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
splitVal := ArValidToAny(a[0])
|
|
||||||
if typeof(splitVal) != "buffer" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected buffer, got " + typeof(splitVal),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var separator = splitVal.([]byte)
|
|
||||||
var result [][]byte
|
|
||||||
start := 0
|
|
||||||
|
|
||||||
for {
|
|
||||||
index := bytes.Index(buf[start:], separator)
|
|
||||||
if index == -1 {
|
|
||||||
result = append(result, buf[start:])
|
|
||||||
break
|
|
||||||
}
|
|
||||||
end := start + index
|
|
||||||
result = append(result, buf[start:end])
|
|
||||||
start = end + len(separator)
|
|
||||||
}
|
|
||||||
var bufoutput = []any{}
|
|
||||||
for _, v := range result {
|
|
||||||
bufoutput = append(bufoutput, ArBuffer(v))
|
|
||||||
}
|
|
||||||
return ArArray(bufoutput), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["slice"] = builtinFunc{
|
|
||||||
"slice",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 2 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 2 arguments, got " + fmt.Sprint(len(a)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typeof(a[0]) != "number" || typeof(a[1]) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected number, got " + typeof(a[0]) + " and " + typeof(a[1]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
start, err := numberToInt64(ArValidToAny(a[0]).(ArObject))
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end, err := numberToInt64(ArValidToAny(a[1]).(ArObject))
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if start < 0 || end < 0 || start > int64(len(buf)) || end > int64(len(buf)) {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Index Error",
|
|
||||||
message: "index out of range",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ArBuffer(buf[start:end]), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["to"] = builtinFunc{
|
|
||||||
"to",
|
|
||||||
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 typeof(a[0]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected string, got " + typeof(a[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Type := ArValidToAny(a[0]).(string)
|
|
||||||
switch Type {
|
|
||||||
case "string":
|
|
||||||
return ArString(string(buf)), ArErr{}
|
|
||||||
case "bytes":
|
|
||||||
output := []any{}
|
|
||||||
for _, v := range buf {
|
|
||||||
output = append(output, ArByte(v))
|
|
||||||
}
|
|
||||||
return ArArray(output), ArErr{}
|
|
||||||
case "array":
|
|
||||||
output := []any{}
|
|
||||||
for _, v := range buf {
|
|
||||||
output = append(output, Number(int64(v)))
|
|
||||||
}
|
|
||||||
return ArArray(output), ArErr{}
|
|
||||||
default:
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected string, bytes or array, got '" + Type + "'",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["append"] = builtinFunc{
|
|
||||||
"append",
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
|
||||||
case int64:
|
|
||||||
if x > 255 || x < 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "ValueError",
|
|
||||||
message: "expected number between 0 and 255, got " + fmt.Sprint(x),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf = append(buf, byte(x))
|
|
||||||
case string:
|
|
||||||
buf = append(buf, []byte(x)...)
|
|
||||||
case []byte:
|
|
||||||
buf = append(buf, x...)
|
|
||||||
case []any:
|
|
||||||
for _, v := range x {
|
|
||||||
switch y := v.(type) {
|
|
||||||
case int64:
|
|
||||||
if y > 255 || y < 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "ValueError",
|
|
||||||
message: "expected number between 0 and 255, got " + fmt.Sprint(y),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf = append(buf, byte(y))
|
|
||||||
default:
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "Cannot convert " + typeof(v) + " to byte",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected string, buffer or array, got " + typeof(x),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
obj.obj["__value__"] = buf
|
|
||||||
return obj, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["insert"] = builtinFunc{
|
|
||||||
"insert",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 2 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 2 arguments, got " + fmt.Sprint(len(a)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
poss := ArValidToAny(a[0])
|
|
||||||
values := ArValidToAny(a[1])
|
|
||||||
if typeof(poss) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected number, got " + typeof(poss),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
posNum, err := numberToInt64(poss.(ArObject))
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch x := values.(type) {
|
|
||||||
case int64:
|
|
||||||
if x > 255 || x < 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "ValueError",
|
|
||||||
message: "expected number between 0 and 255, got " + fmt.Sprint(x),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf = append(buf[:posNum], append([]byte{byte(x)}, buf[posNum:]...)...)
|
|
||||||
case string:
|
|
||||||
buf = append(buf[:posNum], append([]byte(x), buf[posNum:]...)...)
|
|
||||||
case []byte:
|
|
||||||
buf = append(buf[:posNum], append(x, buf[posNum:]...)...)
|
|
||||||
case []any:
|
|
||||||
for _, v := range x {
|
|
||||||
switch y := v.(type) {
|
|
||||||
case int64:
|
|
||||||
if y > 255 || y < 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "ValueError",
|
|
||||||
message: "expected number between 0 and 255, got " + fmt.Sprint(y),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf = append(buf[:posNum], append([]byte{byte(y)}, buf[posNum:]...)...)
|
|
||||||
default:
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "Cannot convert " + typeof(v) + " to byte",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected string or buffer, got " + typeof(x),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
obj.obj["__value__"] = buf
|
|
||||||
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 Number(len(buf)), ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
poss := a[0]
|
|
||||||
if typeof(poss) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected number, got " + typeof(poss),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
posNum, err := numberToInt64(poss.(ArObject))
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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{
|
|
||||||
"remove",
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
poss := ArValidToAny(a[0])
|
|
||||||
if typeof(poss) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected number, got " + typeof(poss),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
posNum, err := numberToInt64(poss.(ArObject))
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if posNum < 0 || posNum >= int64(len(buf)) {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Index Error",
|
|
||||||
message: "index out of range",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf = append(buf[:posNum], buf[posNum+1:]...)
|
|
||||||
obj.obj["__value__"] = buf
|
|
||||||
return obj, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
@@ -14,12 +14,12 @@ func ArgonString(args ...any) (any, ArErr) {
|
|||||||
return ArString(""), ArErr{}
|
return ArString(""), ArErr{}
|
||||||
}
|
}
|
||||||
args[0] = ArValidToAny(args[0])
|
args[0] = ArValidToAny(args[0])
|
||||||
return ArString(anyToArgon(args[0], false, false, 3, 0, false, 0)), ArErr{}
|
return ArString(anyToArgon(args[0], true, false, 3, 0, false, 0)), ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ArgonNumber(args ...any) (any, ArErr) {
|
func ArgonNumber(args ...any) (any, ArErr) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return _zero_Number, ArErr{}
|
return newNumber(), ArErr{}
|
||||||
}
|
}
|
||||||
args[0] = ArValidToAny(args[0])
|
args[0] = ArValidToAny(args[0])
|
||||||
switch x := args[0].(type) {
|
switch x := args[0].(type) {
|
||||||
@@ -27,17 +27,17 @@ func ArgonNumber(args ...any) (any, ArErr) {
|
|||||||
if !isNumber(UNPARSEcode{code: x}) {
|
if !isNumber(UNPARSEcode{code: x}) {
|
||||||
return nil, ArErr{TYPE: "Conversion Error", message: "Cannot convert " + anyToArgon(x, true, true, 3, 0, false, 0) + " to a number", EXISTS: true}
|
return nil, ArErr{TYPE: "Conversion Error", message: "Cannot convert " + anyToArgon(x, true, true, 3, 0, false, 0) + " to a number", EXISTS: true}
|
||||||
}
|
}
|
||||||
N := Number(x)
|
N, _ := newNumber().SetString(x)
|
||||||
return N, ArErr{}
|
return N, ArErr{}
|
||||||
case int64, *big.Int, *big.Rat:
|
case number:
|
||||||
return Number(x), ArErr{}
|
return x, ArErr{}
|
||||||
case bool:
|
case bool:
|
||||||
if x {
|
if x {
|
||||||
return _one_Number, ArErr{}
|
return newNumber().SetInt64(1), ArErr{}
|
||||||
}
|
}
|
||||||
return _zero_Number, ArErr{}
|
return newNumber(), ArErr{}
|
||||||
case nil:
|
case nil:
|
||||||
return _zero_Number, ArErr{}
|
return newNumber(), ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, ArErr{TYPE: "Number Error", message: "Cannot convert " + typeof(args[0]) + " to a number", EXISTS: true}
|
return nil, ArErr{TYPE: "Number Error", message: "Cannot convert " + typeof(args[0]) + " to a number", EXISTS: true}
|
||||||
@@ -48,12 +48,26 @@ func ArgonSqrt(a ...any) (any, ArErr) {
|
|||||||
return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes 1 argument",
|
return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes 1 argument",
|
||||||
EXISTS: true}
|
EXISTS: true}
|
||||||
}
|
}
|
||||||
if _, ok := a[0].(ArObject); !ok {
|
if typeof(a[0]) != "number" {
|
||||||
return nil, ArErr{TYPE: "Runtime Error", message: "can't sqrt type '" + typeof(a[0]) + "'",
|
return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes a number not a '" + typeof(a[0]) + "'",
|
||||||
EXISTS: true}
|
EXISTS: true}
|
||||||
}
|
}
|
||||||
if sqrt_method, ok := a[0].(ArObject).obj["__sqrt__"]; ok {
|
|
||||||
return builtinCall(sqrt_method, []any{})
|
r := a[0].(number)
|
||||||
|
|
||||||
|
if r.Sign() < 0 {
|
||||||
|
return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes a positive number",
|
||||||
|
EXISTS: true}
|
||||||
}
|
}
|
||||||
return nil, ArErr{TYPE: "Runtime Error", message: "can't sqrt type '" + typeof(a[0]) + "'"}
|
|
||||||
|
var x big.Float
|
||||||
|
x.SetPrec(30)
|
||||||
|
x.SetRat(r)
|
||||||
|
|
||||||
|
var s big.Float
|
||||||
|
s.SetPrec(15)
|
||||||
|
s.Sqrt(&x)
|
||||||
|
|
||||||
|
r, _ = s.Rat(nil)
|
||||||
|
return r, ArErr{}
|
||||||
}
|
}
|
||||||
|
|||||||
263
src/built-ins.go
263
src/built-ins.go
@@ -5,20 +5,17 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeGlobal() ArObject {
|
func makeGlobal(allowDocument bool) ArObject {
|
||||||
var vars = anymap{}
|
var vars = anymap{}
|
||||||
vars["global"] = vars
|
vars["global"] = vars
|
||||||
vars["env"] = env
|
|
||||||
vars["term"] = ArTerm
|
vars["term"] = ArTerm
|
||||||
vars["ArgonVersion"] = ArString(VERSION)
|
if allowDocument {
|
||||||
vars["ArgonVersionNumber"] = Number(VERSION_NUM)
|
vars["document"] = ArDocument
|
||||||
|
}
|
||||||
|
vars["js"] = ArJS
|
||||||
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["infinity"] = infinity
|
||||||
"server": builtinFunc{"server", ArSocketServer},
|
|
||||||
"client": builtinFunc{"client", ArSocketClient},
|
|
||||||
})
|
|
||||||
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{}
|
||||||
@@ -50,39 +47,10 @@ 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: "TypeError", message: "Cannot create map from '" + typeof(a[0]) + "'", EXISTS: true}
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot create map from '" + typeof(a[0]) + "'", EXISTS: true}
|
||||||
}}
|
}}
|
||||||
vars["hex"] = builtinFunc{"hex", 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}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
|
||||||
case int64:
|
|
||||||
return ArString(fmt.Sprintf("%x", x)), ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{TYPE: "Type Error", message: "Cannot convert '" + typeof(a[0]) + "' to hex", EXISTS: true}
|
|
||||||
}}
|
|
||||||
vars["buffer"] = builtinFunc{"buffer", 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 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["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 {
|
||||||
return ArArray([]any{}), ArErr{}
|
return ArArray([]any{}), ArErr{}
|
||||||
@@ -127,21 +95,22 @@ func makeGlobal() ArObject {
|
|||||||
return nil, ArErr{TYPE: "round", message: "round takes 1 argument",
|
return nil, ArErr{TYPE: "round", message: "round takes 1 argument",
|
||||||
EXISTS: true}
|
EXISTS: true}
|
||||||
}
|
}
|
||||||
var precision int64 = 0
|
precision := newNumber()
|
||||||
if len(a) > 1 {
|
if len(a) > 1 {
|
||||||
a[1] = ArValidToAny(a[1])
|
|
||||||
switch x := a[1].(type) {
|
switch x := a[1].(type) {
|
||||||
case int64:
|
case number:
|
||||||
|
if !x.IsInt() {
|
||||||
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot round to '" + typeof(a[1]) + "'", EXISTS: true}
|
||||||
|
}
|
||||||
precision = x
|
precision = x
|
||||||
default:
|
default:
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot round to '" + typeof(a[1]) + "'", EXISTS: true}
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot round to '" + typeof(a[1]) + "'", EXISTS: true}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch x := a[0].(type) {
|
switch x := a[0].(type) {
|
||||||
case ArObject:
|
case number:
|
||||||
if round_method, ok := x.obj["__round__"]; ok {
|
return round(newNumber().Set(x), int(precision.Num().Int64())), ArErr{}
|
||||||
return builtinCall(round_method, []any{Number(precision)})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot round '" + typeof(a[0]) + "'", EXISTS: true}
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot round '" + typeof(a[0]) + "'", EXISTS: true}
|
||||||
}}
|
}}
|
||||||
@@ -151,10 +120,8 @@ func makeGlobal() ArObject {
|
|||||||
EXISTS: true}
|
EXISTS: true}
|
||||||
}
|
}
|
||||||
switch x := a[0].(type) {
|
switch x := a[0].(type) {
|
||||||
case ArObject:
|
case number:
|
||||||
if floor_method, ok := x.obj["__floor__"]; ok {
|
return floor(x), ArErr{}
|
||||||
return builtinCall(floor_method, []any{})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot floor '" + typeof(a[0]) + "'", EXISTS: true}
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot floor '" + typeof(a[0]) + "'", EXISTS: true}
|
||||||
}}
|
}}
|
||||||
@@ -163,11 +130,10 @@ func makeGlobal() ArObject {
|
|||||||
return nil, ArErr{TYPE: "ceil", message: "ceil takes 1 argument",
|
return nil, ArErr{TYPE: "ceil", message: "ceil takes 1 argument",
|
||||||
EXISTS: true}
|
EXISTS: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch x := a[0].(type) {
|
switch x := a[0].(type) {
|
||||||
case ArObject:
|
case number:
|
||||||
if ceil_method, ok := x.obj["__ceil__"]; ok {
|
return ceil(x), ArErr{}
|
||||||
return builtinCall(ceil_method, []any{})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot ceil '" + typeof(a[0]) + "'", EXISTS: true}
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot ceil '" + typeof(a[0]) + "'", EXISTS: true}
|
||||||
}}
|
}}
|
||||||
@@ -188,32 +154,8 @@ func makeGlobal() ArObject {
|
|||||||
vars["cot"] = ArCot
|
vars["cot"] = ArCot
|
||||||
vars["arccot"] = ArArccot
|
vars["arccot"] = ArArccot
|
||||||
vars["todeg"] = ArToDeg
|
vars["todeg"] = ArToDeg
|
||||||
vars["colour"] = ArColour
|
|
||||||
vars["torad"] = ArToRad
|
vars["torad"] = ArToRad
|
||||||
vars["fraction"] = builtinFunc{"fraction", func(a ...any) (any, ArErr) {
|
vars["abs"] = ArAbs
|
||||||
if len(a) == 0 {
|
|
||||||
return nil, ArErr{TYPE: "fraction", message: "fraction takes 1 argument",
|
|
||||||
EXISTS: true}
|
|
||||||
}
|
|
||||||
switch x := a[0].(type) {
|
|
||||||
case ArObject:
|
|
||||||
if callable, ok := x.obj["__fraction__"]; ok {
|
|
||||||
resp, err := runCall(
|
|
||||||
call{
|
|
||||||
Callable: callable,
|
|
||||||
Args: []any{},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return resp, ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ArErr{TYPE: "Type Error", message: "Cannot fraction '" + typeof(a[0]) + "'", EXISTS: true}
|
|
||||||
}}
|
|
||||||
vars["dir"] = builtinFunc{"dir", func(a ...any) (any, ArErr) {
|
vars["dir"] = builtinFunc{"dir", func(a ...any) (any, ArErr) {
|
||||||
if len(a) == 0 {
|
if len(a) == 0 {
|
||||||
return ArArray([]any{}), ArErr{}
|
return ArArray([]any{}), ArErr{}
|
||||||
@@ -223,147 +165,74 @@ func makeGlobal() ArObject {
|
|||||||
case ArObject:
|
case ArObject:
|
||||||
newarray := []any{}
|
newarray := []any{}
|
||||||
for key := range x.obj {
|
for key := range x.obj {
|
||||||
newarray = append(newarray, AnyToArValid(key))
|
newarray = append(newarray, key)
|
||||||
}
|
}
|
||||||
return ArArray(newarray), ArErr{}
|
return ArArray(newarray), ArErr{}
|
||||||
}
|
}
|
||||||
return ArArray([]any{}), ArErr{}
|
return ArArray([]any{}), ArErr{}
|
||||||
}}
|
}}
|
||||||
vars["subprocess"] = builtinFunc{"subprocess", ArSubprocess}
|
vars["subprocess"] = builtinFunc{"subprocess", ArSubprocess}
|
||||||
|
vars["object"] = builtinFunc{"object", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot create class from '" + typeof(a[0]) + "'", EXISTS: true}
|
||||||
|
}
|
||||||
|
switch x := a[0].(type) {
|
||||||
|
case ArObject:
|
||||||
|
if typeof(x) == "object" {
|
||||||
|
return x, ArErr{}
|
||||||
|
}
|
||||||
|
newclass := ArObject{obj: anymap{}}
|
||||||
|
for key, val := range x.obj {
|
||||||
|
newclass.obj[key] = val
|
||||||
|
}
|
||||||
|
return newclass, ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot create class from '" + typeof(a[0]) + "'", EXISTS: true}
|
||||||
|
}}
|
||||||
vars["sequence"] = builtinFunc{"sequence", ArSequence}
|
vars["sequence"] = builtinFunc{"sequence", ArSequence}
|
||||||
vars["exit"] = 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)
|
||||||
}
|
}
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
switch x := a[0].(type) {
|
||||||
case int64:
|
case number:
|
||||||
os.Exit(int(x))
|
os.Exit(int(floor(x).Num().Int64()))
|
||||||
return nil, ArErr{}
|
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}}
|
}}
|
||||||
|
vars["error"] = builtinFunc{"error", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) < 1 || len(a) > 2 {
|
||||||
|
return nil, ArErr{TYPE: "error", message: "error takes 1 or 2 arguments, got " + fmt.Sprint(len(a)), EXISTS: true}
|
||||||
|
}
|
||||||
|
if len(a) == 1 {
|
||||||
|
a[0] = ArValidToAny(a[0])
|
||||||
|
switch x := a[0].(type) {
|
||||||
|
case string:
|
||||||
|
return nil, ArErr{TYPE: "Error", message: x, EXISTS: true}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a[0] = ArValidToAny(a[0])
|
||||||
|
a[1] = ArValidToAny(a[1])
|
||||||
|
switch x := a[0].(type) {
|
||||||
|
case string:
|
||||||
|
switch y := a[1].(type) {
|
||||||
|
case string:
|
||||||
|
return nil, ArErr{TYPE: x, message: y, EXISTS: true}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot create error from '" + typeof(a[0]) + "'", EXISTS: true}
|
||||||
|
}}
|
||||||
vars["chr"] = builtinFunc{"chr", func(a ...any) (any, ArErr) {
|
vars["chr"] = builtinFunc{"chr", func(a ...any) (any, ArErr) {
|
||||||
if len(a) != 1 {
|
if len(a) != 1 {
|
||||||
return nil, ArErr{TYPE: "chr", message: "chr takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
|
return nil, ArErr{TYPE: "chr", message: "chr takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
|
||||||
}
|
}
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
switch x := a[0].(type) {
|
||||||
case int64:
|
case number:
|
||||||
return string([]rune{rune(x)}), ArErr{}
|
return string([]rune{rune(floor(x).Num().Int64())}), ArErr{}
|
||||||
}
|
}
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot convert '" + typeof(a[0]) + "' to string", EXISTS: true}
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot convert '" + typeof(a[0]) + "' to string", EXISTS: true}
|
||||||
}}
|
}}
|
||||||
vars["ord"] = builtinFunc{"ord", func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 1 {
|
|
||||||
return nil, ArErr{TYPE: "ord", message: "ord takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
|
||||||
case string:
|
|
||||||
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 Number(int64([]rune(x)[0])), ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{TYPE: "Type Error", message: "Cannot convert '" + typeof(a[0]) + "' to string", EXISTS: true}
|
|
||||||
}}
|
|
||||||
vars["max"] = builtinFunc{"max", func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 1 {
|
|
||||||
return nil, ArErr{TYPE: "runtime Error", message: "max takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
|
||||||
case []any:
|
|
||||||
if len(x) == 0 {
|
|
||||||
return nil, ArErr{TYPE: "runtime Error", message: "max takes a non-empty array", EXISTS: true}
|
|
||||||
}
|
|
||||||
var max ArObject
|
|
||||||
for i, v := range x {
|
|
||||||
switch x := v.(type) {
|
|
||||||
case ArObject:
|
|
||||||
if i == 0 {
|
|
||||||
max = x
|
|
||||||
} else {
|
|
||||||
compared, err := CompareObjects(max, x)
|
|
||||||
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
compared_int, Err := numberToInt64(compared)
|
|
||||||
|
|
||||||
if Err != nil {
|
|
||||||
return nil, ArErr{TYPE: "Type Error", message: Err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if compared_int == 1 {
|
|
||||||
max = x
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return max, ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{TYPE: "Type Error", message: "Cannot get max of type '" + typeof(a[0]) + "'", EXISTS: true}
|
|
||||||
}}
|
|
||||||
vars["min"] = builtinFunc{"min", func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 1 {
|
|
||||||
return nil, ArErr{TYPE: "runtime Error", message: "max takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
|
||||||
case []any:
|
|
||||||
if len(x) == 0 {
|
|
||||||
return nil, ArErr{TYPE: "runtime Error", message: "max takes a non-empty array", EXISTS: true}
|
|
||||||
}
|
|
||||||
var max ArObject
|
|
||||||
for i, v := range x {
|
|
||||||
switch x := v.(type) {
|
|
||||||
case ArObject:
|
|
||||||
if i == 0 {
|
|
||||||
max = x
|
|
||||||
} else {
|
|
||||||
compared, err := CompareObjects(max, x)
|
|
||||||
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
compared_int, Err := numberToInt64(compared)
|
|
||||||
|
|
||||||
if Err != nil {
|
|
||||||
return nil, ArErr{TYPE: "Type Error", message: Err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if compared_int == -1 {
|
|
||||||
max = x
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return max, ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{TYPE: "Type Error", message: "Cannot get max of type '" + typeof(a[0]) + "'", EXISTS: true}
|
|
||||||
}}
|
|
||||||
vars["path"] = ArPath
|
|
||||||
vars["typeof"] = builtinFunc{"typeof", func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 1 {
|
|
||||||
return nil, ArErr{TYPE: "typeof", message: "typeof takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
|
|
||||||
}
|
|
||||||
return ArString(typeof(a[0])), ArErr{}
|
|
||||||
}}
|
|
||||||
vars["sha256"] = builtinFunc{"sha256", func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 1 {
|
|
||||||
return nil, ArErr{TYPE: "sha256", message: "sha256 takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
switch x := a[0].(type) {
|
|
||||||
case string:
|
|
||||||
return ArString(sha256Hash(x)), ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{TYPE: "Type Error", message: "Cannot hash type '" + typeof(a[0]) + "'", EXISTS: true}
|
|
||||||
}}
|
|
||||||
return Map(vars)
|
return Map(vars)
|
||||||
}
|
}
|
||||||
|
|||||||
64
src/call.go
64
src/call.go
@@ -8,11 +8,11 @@ import (
|
|||||||
var callCompile = makeRegex("( *)(.|\n)+\\((.|\n)*\\)( *)")
|
var callCompile = makeRegex("( *)(.|\n)+\\((.|\n)*\\)( *)")
|
||||||
|
|
||||||
type call struct {
|
type call struct {
|
||||||
Callable any
|
callable any
|
||||||
Args []any
|
args []any
|
||||||
Code string
|
code string
|
||||||
Line int
|
line int
|
||||||
Path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Callable struct {
|
type Callable struct {
|
||||||
@@ -32,60 +32,59 @@ func parseCall(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
|
|||||||
trim := strings.TrimSpace(code.code)
|
trim := strings.TrimSpace(code.code)
|
||||||
trim = trim[:len(trim)-1]
|
trim = trim[:len(trim)-1]
|
||||||
splitby := strings.Split(trim, "(")
|
splitby := strings.Split(trim, "(")
|
||||||
|
|
||||||
|
var works bool
|
||||||
|
var callable any
|
||||||
|
var arguments []any
|
||||||
for i := 1; i < len(splitby); i++ {
|
for i := 1; i < len(splitby); i++ {
|
||||||
name := strings.Join(splitby[0:i], "(")
|
name := strings.Join(splitby[0:i], "(")
|
||||||
argstr := strings.Join(splitby[i:], "(")
|
argstr := strings.Join(splitby[i:], "(")
|
||||||
args, success, argserr := getValuesFromLetter(argstr, ",", index, codelines, false)
|
args, success, argserr := getValuesFromLetter(argstr, ",", index, codelines, false)
|
||||||
|
arguments = args
|
||||||
if !success {
|
if !success {
|
||||||
if i == len(splitby)-1 {
|
if i == len(splitby)-1 {
|
||||||
return nil, false, argserr, 1
|
return nil, false, argserr, 1
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
resp, worked, err, linecount := translateVal(UNPARSEcode{code: name, realcode: code.realcode, line: index + 1, path: code.path}, index, codelines, 0)
|
resp, worked, _, _ := translateVal(UNPARSEcode{code: name, realcode: code.realcode, line: index + 1, path: code.path}, index, codelines, 0)
|
||||||
if !worked {
|
if !worked {
|
||||||
if i == len(splitby)-1 {
|
if i == len(splitby)-1 {
|
||||||
return nil, false, err, 1
|
return nil, false, ArErr{"Syntax Error", "invalid callable", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return call{Callable: resp, Args: args, Line: code.line, Code: code.realcode, Path: code.path}, true, ArErr{}, linecount
|
works = true
|
||||||
|
callable = resp
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
if !works {
|
||||||
return nil, false, ArErr{"Syntax Error", "invalid call", code.line, code.path, code.realcode, true}, 1
|
return nil, false, ArErr{"Syntax Error", "invalid call", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
|
return call{callable: callable, args: arguments, line: code.line, code: code.realcode, path: code.path}, true, ArErr{}, 1
|
||||||
|
}
|
||||||
|
|
||||||
func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
||||||
var callable any = c.Callable
|
var callable any
|
||||||
switch x := c.Callable.(type) {
|
switch x := c.callable.(type) {
|
||||||
case builtinFunc:
|
case builtinFunc:
|
||||||
callable = x
|
callable = x
|
||||||
case Callable:
|
case Callable:
|
||||||
callable = x
|
callable = x
|
||||||
default:
|
default:
|
||||||
callable_, err := runVal(c.Callable, stack, stacklevel+1)
|
callable_, err := runVal(c.callable, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
switch x := callable_.(type) {
|
switch x := callable_.(type) {
|
||||||
case ArObject:
|
case ArObject:
|
||||||
callable_, err := mapGet(ArMapGet{
|
callable_ = x.obj["__call__"]
|
||||||
x,
|
|
||||||
[]any{"__call__"},
|
|
||||||
true,
|
|
||||||
c.Line,
|
|
||||||
c.Code,
|
|
||||||
c.Path,
|
|
||||||
}, stack, stacklevel+1)
|
|
||||||
if !err.EXISTS {
|
|
||||||
callable = callable_
|
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
callable = callable_
|
callable = callable_
|
||||||
}
|
}
|
||||||
}
|
|
||||||
args := []any{}
|
args := []any{}
|
||||||
level := append(stack, newscope())
|
level := append(stack, newscope())
|
||||||
for _, arg := range c.Args {
|
for _, arg := range c.args {
|
||||||
resp, err := runVal(arg, level, stacklevel+1)
|
resp, err := runVal(arg, level, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -94,38 +93,35 @@ func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
switch x := callable.(type) {
|
switch x := callable.(type) {
|
||||||
case builtinFunc:
|
case builtinFunc:
|
||||||
debugPrintln(x.name, args)
|
|
||||||
resp, err := x.FUNC(args...)
|
resp, err := x.FUNC(args...)
|
||||||
resp = AnyToArValid(resp)
|
resp = AnyToArValid(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
if err.line == 0 {
|
if err.line == 0 {
|
||||||
err.line = c.Line
|
err.line = c.line
|
||||||
}
|
}
|
||||||
if err.path == "" {
|
if err.path == "" {
|
||||||
err.path = c.Path
|
err.path = c.path
|
||||||
}
|
}
|
||||||
if err.code == "" {
|
if err.code == "" {
|
||||||
err.code = c.Code
|
err.code = c.code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resp, err
|
return resp, err
|
||||||
case Callable:
|
case Callable:
|
||||||
debugPrintln(x.name, args)
|
|
||||||
if len(x.params) != len(args) {
|
if len(x.params) != len(args) {
|
||||||
return nil, ArErr{"Runtime Error", "expected " + fmt.Sprint(len(x.params)) + " arguments, got " + fmt.Sprint(len(args)), c.Line, c.Path, c.Code, true}
|
return nil, ArErr{"Runtime Error", "expected " + fmt.Sprint(len(x.params)) + " arguments, got " + fmt.Sprint(len(args)), c.line, c.path, c.code, true}
|
||||||
}
|
}
|
||||||
l := anymap{}
|
l := anymap{}
|
||||||
for i, param := range x.params {
|
for i, param := range x.params {
|
||||||
l[param] = args[i]
|
l[param] = args[i]
|
||||||
}
|
}
|
||||||
resp, err := runVal(x.run, append(x.stack, Map(l)), stacklevel+1)
|
resp, err := runVal(x.run, append(x.stack, Map(l)), stacklevel+1)
|
||||||
return openReturn(resp), err
|
return ThrowOnNonLoop(openReturn(resp), err)
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.Line, c.Path, c.Code, true}
|
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
|
||||||
}
|
}
|
||||||
|
|
||||||
func builtinCall(callable any, args []any) (any, ArErr) {
|
func builtinCall(callable any, args []any) (any, ArErr) {
|
||||||
debugPrintln(callable, args)
|
|
||||||
|
|
||||||
switch x := callable.(type) {
|
switch x := callable.(type) {
|
||||||
case builtinFunc:
|
case builtinFunc:
|
||||||
@@ -141,7 +137,7 @@ func builtinCall(callable any, args []any) (any, ArErr) {
|
|||||||
level.obj[param] = args[i]
|
level.obj[param] = args[i]
|
||||||
}
|
}
|
||||||
resp, err := runVal(x.run, append(x.stack, level), 0)
|
resp, err := runVal(x.run, append(x.stack, level), 0)
|
||||||
return openReturn(resp), err
|
return ThrowOnNonLoop(openReturn(resp), err)
|
||||||
}
|
}
|
||||||
return nil, ArErr{TYPE: "Runtime Error", message: "type '" + typeof(callable) + "' is not callable", EXISTS: true}
|
return nil, ArErr{TYPE: "Runtime Error", message: "type '" + typeof(callable) + "' is not callable", EXISTS: true}
|
||||||
}
|
}
|
||||||
|
|||||||
104
src/colour.go
104
src/colour.go
@@ -1,104 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/fatih/color"
|
|
||||||
"github.com/jwalton/go-supportscolor"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ArColour = Map(
|
|
||||||
anymap{
|
|
||||||
"set": builtinFunc{"set", func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 2 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "set() takes exactly 2 argument (" + fmt.Sprint(len(a)) + " given)",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var c *color.Color
|
|
||||||
var s string
|
|
||||||
if x, ok := a[0].(ArObject); ok {
|
|
||||||
colour_int64, err := numberToInt64(x)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c = color.New(color.Attribute(colour_int64))
|
|
||||||
} else {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "set() argument 1 must be an number, not " + typeof(a[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typeof(a[1]) == "string" {
|
|
||||||
s = ArValidToAny(a[1]).(string)
|
|
||||||
} else {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "set() argument 2 must be a string, not " + typeof(a[1]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if supportscolor.Stdout().SupportsColor {
|
|
||||||
return c.Sprint(s), ArErr{}
|
|
||||||
} else {
|
|
||||||
return s, ArErr{}
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
"bg": Map(
|
|
||||||
anymap{
|
|
||||||
"black": Number(int64(color.BgBlack)),
|
|
||||||
"red": Number(int64(color.BgRed)),
|
|
||||||
"green": Number(int64(color.BgGreen)),
|
|
||||||
"yellow": Number(int64(color.BgYellow)),
|
|
||||||
"blue": Number(int64(color.BgBlue)),
|
|
||||||
"magenta": Number(int64(color.BgMagenta)),
|
|
||||||
"cyan": Number(int64(color.BgCyan)),
|
|
||||||
"white": Number(int64(color.BgWhite)),
|
|
||||||
"hiBlack": Number(int64(color.BgHiBlack)),
|
|
||||||
"hiRed": Number(int64(color.BgHiRed)),
|
|
||||||
"hiGreen": Number(int64(color.BgHiGreen)),
|
|
||||||
"hiYellow": Number(int64(color.BgHiYellow)),
|
|
||||||
"hiBlue": Number(int64(color.BgHiBlue)),
|
|
||||||
"hiMagenta": Number(int64(color.BgHiMagenta)),
|
|
||||||
"hiCyan": Number(int64(color.BgHiCyan)),
|
|
||||||
"hiWhite": Number(int64(color.BgHiWhite)),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
"fg": Map(
|
|
||||||
anymap{
|
|
||||||
"black": Number(int64(color.FgBlack)),
|
|
||||||
"red": Number(int64(color.FgRed)),
|
|
||||||
"green": Number(int64(color.FgGreen)),
|
|
||||||
"yellow": Number(int64(color.FgYellow)),
|
|
||||||
"blue": Number(int64(color.FgBlue)),
|
|
||||||
"magenta": Number(int64(color.FgMagenta)),
|
|
||||||
"cyan": Number(int64(color.FgCyan)),
|
|
||||||
"white": Number(int64(color.FgWhite)),
|
|
||||||
"hiBlack": Number(int64(color.FgHiBlack)),
|
|
||||||
"hiRed": Number(int64(color.FgHiRed)),
|
|
||||||
"hiGreen": Number(int64(color.FgHiGreen)),
|
|
||||||
"hiYellow": Number(int64(color.FgHiYellow)),
|
|
||||||
"hiBlue": Number(int64(color.FgHiBlue)),
|
|
||||||
"hiMagenta": Number(int64(color.FgHiMagenta)),
|
|
||||||
"hiCyan": Number(int64(color.FgHiCyan)),
|
|
||||||
"hiWhite": Number(int64(color.FgHiWhite)),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
"reset": Number(int64(color.Reset)),
|
|
||||||
"bold": Number(int64(color.Bold)),
|
|
||||||
"faint": Number(int64(color.Faint)),
|
|
||||||
"italic": Number(int64(color.Italic)),
|
|
||||||
"underline": Number(int64(color.Underline)),
|
|
||||||
"blinkSlow": Number(int64(color.BlinkSlow)),
|
|
||||||
"blinkRapid": Number(int64(color.BlinkRapid)),
|
|
||||||
"reverseVideo": Number(int64(color.ReverseVideo)),
|
|
||||||
"concealed": Number(int64(color.Concealed)),
|
|
||||||
"crossedOut": Number(int64(color.CrossedOut)),
|
|
||||||
})
|
|
||||||
@@ -24,7 +24,7 @@ func parseComment(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bo
|
|||||||
if isBlank(UNPARSEcode{code: joined, realcode: code.realcode, line: code.line, path: code.path}) {
|
if isBlank(UNPARSEcode{code: joined, realcode: code.realcode, line: code.line, path: code.path}) {
|
||||||
return nil, true, ArErr{}, step
|
return nil, true, ArErr{}, step
|
||||||
}
|
}
|
||||||
resp, worked, _, s := translateVal(UNPARSEcode{code: joined, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 3)
|
resp, worked, _, s := translateVal(UNPARSEcode{code: joined, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 2)
|
||||||
step += s - 1
|
step += s - 1
|
||||||
if worked {
|
if worked {
|
||||||
return resp, true, ArErr{}, step
|
return resp, true, ArErr{}, step
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
var website = "https://argon.wbell.dev/"
|
var websiteLang = "https://argon.wbell.dev/"
|
||||||
var docs = "https://argon.wbell.dev/docs/"
|
var docs = "https://argon.wbell.dev/docs/"
|
||||||
var mainrepo = "https://github.com/Open-Argon/argon-v3"
|
var mainrepo = "https://github.com/Open-Argon/argon-v3"
|
||||||
var mainissuesPage = "https://github.com/Open-Argon/argon-v3/issues"
|
var mainissuesPage = "https://github.com/Open-Argon/argon-v3/issues"
|
||||||
var fork = false
|
var fork = true
|
||||||
var forkrepo = ""
|
var forkrepo = "https://github.com/Open-Argon/argon-v3.wasm"
|
||||||
var forkissuesPage = ""
|
var forkissuesPage = "https://github.com/Open-Argon/argon-v3.wasm/issues"
|
||||||
|
|||||||
44
src/debug.go
44
src/debug.go
@@ -1,44 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var debug = os.Getenv("__ARGON_DEBUG__") == "true"
|
|
||||||
|
|
||||||
var __debugPrints = [][]any{}
|
|
||||||
var __debugPrintsLock = sync.RWMutex{}
|
|
||||||
|
|
||||||
func debugInit() {
|
|
||||||
if debug {
|
|
||||||
fmt.Println("In debug mode...")
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
fmt.Println("debugPrintln: panic:", r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
for {
|
|
||||||
__debugPrintsLock.RLock()
|
|
||||||
for _, v := range __debugPrints {
|
|
||||||
fmt.Println(v...)
|
|
||||||
}
|
|
||||||
__debugPrintsLock.RUnlock()
|
|
||||||
__debugPrintsLock.Lock()
|
|
||||||
__debugPrints = [][]any{}
|
|
||||||
__debugPrintsLock.Unlock()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func debugPrintln(a ...any) {
|
|
||||||
switch debug {
|
|
||||||
case true:
|
|
||||||
__debugPrintsLock.Lock()
|
|
||||||
__debugPrints = append(__debugPrints, a)
|
|
||||||
__debugPrintsLock.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
213
src/document.go
Normal file
213
src/document.go
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall/js"
|
||||||
|
)
|
||||||
|
|
||||||
|
func windowElement(element js.Value) ArObject {
|
||||||
|
return ArObject{
|
||||||
|
obj: anymap{
|
||||||
|
"innerHTML": builtinFunc{"innerHTML", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) > 0 {
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "innerHTML only accepts strings", 0, "", "", true}
|
||||||
|
}
|
||||||
|
element.Set("innerHTML", args[0].(string))
|
||||||
|
}
|
||||||
|
return element.Get("innerHTML").String(), ArErr{}
|
||||||
|
}},
|
||||||
|
"innerText": builtinFunc{"innerText", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) > 0 {
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "innerText only accepts strings", 0, "", "", true}
|
||||||
|
}
|
||||||
|
element.Set("innerText", args[0].(string))
|
||||||
|
}
|
||||||
|
return element.Get("innerText").String(), ArErr{}
|
||||||
|
}},
|
||||||
|
"addEventListener": builtinFunc{"addEventListener", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 2 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for addEventListener", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "addEventListener's first argument must be a string", 0, "", "", true}
|
||||||
|
}
|
||||||
|
event := args[0].(string)
|
||||||
|
if typeof(args[1]) != "function" {
|
||||||
|
return nil, ArErr{"Argument Error", "addEventListener's second argument must be a function", 0, "", "", true}
|
||||||
|
}
|
||||||
|
callable := args[1]
|
||||||
|
element.Call("addEventListener", event, js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
|
runCall(call{
|
||||||
|
callable: callable,
|
||||||
|
args: []any{},
|
||||||
|
}, stack{}, 0)
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"removeEventListener": builtinFunc{"removeEventListener", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 2 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for removeEventListener", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "removeEventListener's first argument must be a string", 0, "", "", true}
|
||||||
|
}
|
||||||
|
event := args[0].(string)
|
||||||
|
if typeof(args[1]) != "function" {
|
||||||
|
return nil, ArErr{"Argument Error", "removeEventListener's second argument must be a function", 0, "", "", true}
|
||||||
|
}
|
||||||
|
callable := args[1]
|
||||||
|
element.Call("removeEventListener", event, js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
|
runCall(call{
|
||||||
|
callable: callable,
|
||||||
|
args: []any{},
|
||||||
|
}, stack{}, 0)
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"appendChild": builtinFunc{"appendChild", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for appendChild", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "map" {
|
||||||
|
return nil, ArErr{"Argument Error", "appendChild's first argument must be a map", 0, "", "", true}
|
||||||
|
}
|
||||||
|
child := args[0].(anymap)
|
||||||
|
if child["__TYPE__"] != "windowElement" {
|
||||||
|
return nil, ArErr{"Argument Error", "appendChild's first argument must be an element", 0, "", "", true}
|
||||||
|
}
|
||||||
|
element.Call("appendChild", child["__element__"])
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"removeChild": builtinFunc{"removeChild", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for removeChild", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "map" {
|
||||||
|
return nil, ArErr{"Argument Error", "removeChild's first argument must be a map", 0, "", "", true}
|
||||||
|
}
|
||||||
|
child := args[0].(anymap)
|
||||||
|
if child["__TYPE__"] != "windowElement" {
|
||||||
|
return nil, ArErr{"Argument Error", "removeChild's first argument must be an element", 0, "", "", true}
|
||||||
|
}
|
||||||
|
element.Call("removeChild", child["__element__"])
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"setAttribute": builtinFunc{"setAttribute", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 2 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for setAttribute", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "setAttribute's first argument must be a string", 0, "", "", true}
|
||||||
|
}
|
||||||
|
element.Call("setAttribute", args[0].(string), anyToArgon(args[1], false, false, 3, 0, false, 0))
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"__element__": element,
|
||||||
|
"__TYPE__": "windowElement",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArDocument = Map(
|
||||||
|
anymap{
|
||||||
|
"body": builtinFunc{"getElementById", func(args ...any) (any, ArErr) {
|
||||||
|
return windowElement(js.Global().Get("document").Get("body")), ArErr{}
|
||||||
|
}},
|
||||||
|
"head": builtinFunc{"getElementById", func(args ...any) (any, ArErr) {
|
||||||
|
return windowElement(js.Global().Get("document").Get("head")), ArErr{}
|
||||||
|
}},
|
||||||
|
"getElementById": builtinFunc{"getElementById", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for getElementById", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "getElementById's first argument must be a string", 0, "", "", true}
|
||||||
|
}
|
||||||
|
id := args[0].(string)
|
||||||
|
result := js.Global().Get("document").Call("getElementById", id)
|
||||||
|
if js.Null().Equal(result) {
|
||||||
|
return nil, ArErr{}
|
||||||
|
}
|
||||||
|
return windowElement(result), ArErr{}
|
||||||
|
}},
|
||||||
|
"createElement": builtinFunc{"createElement", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for createElement", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "createElement's first argument must be a string", 0, "", "", true}
|
||||||
|
}
|
||||||
|
tag := args[0].(string)
|
||||||
|
return windowElement(js.Global().Get("document").Call("createElement", tag)), ArErr{}
|
||||||
|
}},
|
||||||
|
"createTextNode": builtinFunc{"createTextNode", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for createTextNode", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "createTextNode's first argument must be a string", 0, "", "", true}
|
||||||
|
}
|
||||||
|
text := args[0].(string)
|
||||||
|
return windowElement(js.Global().Get("document").Call("createTextNode", text)), ArErr{}
|
||||||
|
}},
|
||||||
|
"createComment": builtinFunc{"createComment", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for createComment", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "createComment's first argument must be a string", 0, "", "", true}
|
||||||
|
}
|
||||||
|
text := args[0].(string)
|
||||||
|
return windowElement(js.Global().Get("document").Call("createComment", text)), ArErr{}
|
||||||
|
}},
|
||||||
|
"createDocumentFragment": builtinFunc{"createDocumentFragment", func(args ...any) (any, ArErr) {
|
||||||
|
return windowElement(js.Global().Get("document").Call("createDocumentFragment")), ArErr{}
|
||||||
|
}},
|
||||||
|
"addEventListener": builtinFunc{"addEventListener", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 2 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for addEventListener", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "addEventListener's first argument must be a string", 0, "", "", true}
|
||||||
|
}
|
||||||
|
event := args[0].(string)
|
||||||
|
if typeof(args[1]) != "function" {
|
||||||
|
return nil, ArErr{"Argument Error", "addEventListener's second argument must be a function", 0, "", "", true}
|
||||||
|
}
|
||||||
|
callable := args[1]
|
||||||
|
js.Global().Get("document").Call("addEventListener", event, js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
|
runCall(call{
|
||||||
|
callable: callable,
|
||||||
|
args: []any{},
|
||||||
|
}, stack{}, 0)
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"removeEventListener": builtinFunc{"removeEventListener", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) < 2 {
|
||||||
|
return nil, ArErr{"Argument Error", "Not enough arguments for removeEventListener", 0, "", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return nil, ArErr{"Argument Error", "removeEventListener's first argument must be a string", 0, "", "", true}
|
||||||
|
}
|
||||||
|
event := args[0].(string)
|
||||||
|
if typeof(args[1]) != "function" {
|
||||||
|
return nil, ArErr{"Argument Error", "removeEventListener's second argument must be a function", 0, "", "", true}
|
||||||
|
}
|
||||||
|
callable := args[1]
|
||||||
|
js.Global().Get("document").Call("removeEventListener", event, js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
|
runCall(call{
|
||||||
|
callable: callable,
|
||||||
|
args: []any{},
|
||||||
|
}, stack{}, 0)
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"__TYPE__": "document",
|
||||||
|
},
|
||||||
|
)
|
||||||
@@ -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 allCodelines = []UNPARSEcode{}
|
var i = index + 1
|
||||||
i := index + 1
|
translated := []any{}
|
||||||
for ; i < len(codelines); i++ {
|
for i < len(codelines) {
|
||||||
|
|
||||||
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,38 +34,31 @@ 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", code.line, code.path, codelines[i].code, true}, 1
|
return nil, false, ArErr{"Syntax Error", "invalid indent", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
val, _, err, step := translateVal(codelines[i], i, codelines, 3)
|
val, _, err, step := translateVal(codelines[i], i, codelines, 2)
|
||||||
i += step
|
i += step
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, false, err, i - index
|
return nil, false, err, i - index
|
||||||
}
|
}
|
||||||
translated = append(translated, val)
|
translated = append(translated, val)
|
||||||
}
|
}
|
||||||
return dowrap{run: translated, line: code.line, path: code.path, code: code.realcode}, true, ArErr{}, finalLines - index
|
return dowrap{run: translated, line: code.line, path: code.path, code: code.realcode}, true, ArErr{}, i - 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, newstackCopy, stacklevel+1)
|
val, err := runVal(v, newstack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
switch x := val.(type) {
|
switch x := val.(type) {
|
||||||
case Return, Break, Continue:
|
case Return:
|
||||||
|
return x, ArErr{}
|
||||||
|
case Break:
|
||||||
return x, ArErr{}
|
return x, ArErr{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/env.go
29
src/env.go
@@ -1,29 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// get the environment variables
|
|
||||||
func getEnv() ArObject {
|
|
||||||
env := make(anymap)
|
|
||||||
for _, e := range os.Environ() {
|
|
||||||
pair := strings.Split(e, "=")
|
|
||||||
env[pair[0]] = ArString(pair[1])
|
|
||||||
}
|
|
||||||
err := godotenv.Load(".env")
|
|
||||||
if err == nil {
|
|
||||||
values, err := godotenv.Read()
|
|
||||||
if err == nil {
|
|
||||||
for k, v := range values {
|
|
||||||
env[k] = ArString(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Map(env)
|
|
||||||
}
|
|
||||||
|
|
||||||
var env = getEnv()
|
|
||||||
33
src/error.go
33
src/error.go
@@ -2,6 +2,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/jwalton/go-supportscolor"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArErr struct {
|
type ArErr struct {
|
||||||
@@ -13,38 +15,15 @@ type ArErr struct {
|
|||||||
EXISTS bool
|
EXISTS bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func ArThrowError(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 2 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "throwError takes 2 arguments, " + fmt.Sprint(len(a)) + " given",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
} else if typeof(a[0]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "throwError type must be a string",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
} else if typeof(a[1]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "throwError message must be a string",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: ArValidToAny(a[0]).(string),
|
|
||||||
message: ArValidToAny(a[1]).(string),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func panicErr(err ArErr) {
|
func panicErr(err ArErr) {
|
||||||
if err.code != "" && err.line != 0 && err.path != "" {
|
if err.code != "" && err.line != 0 && err.path != "" {
|
||||||
fmt.Println(" File:", err.path+":"+fmt.Sprint(err.line))
|
fmt.Println(" File:", err.path+":"+fmt.Sprint(err.line))
|
||||||
fmt.Println(" " + err.code)
|
fmt.Println(" " + err.code)
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
if supportscolor.Stdout().SupportsColor {
|
||||||
fmt.Printf("\x1b[%dm%s\x1b[0m", 91, fmt.Sprint(err.TYPE, ": ", err.message, "\n"))
|
fmt.Printf("\x1b[%dm%s\x1b[0m", 91, fmt.Sprint(err.TYPE, ": ", err.message, "\n"))
|
||||||
|
} else {
|
||||||
|
fmt.Println(fmt.Sprint(err.TYPE, ": ", err.message))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@@ -28,26 +28,36 @@ func isFactorial(code UNPARSEcode) bool {
|
|||||||
return factorialCompiled.MatchString(code.code)
|
return factorialCompiled.MatchString(code.code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fact(n number) number {
|
||||||
|
if n.Cmp(newNumber().SetInt64(1000)) >= 0 {
|
||||||
|
return infinity
|
||||||
|
} else if n.Cmp(newNumber().SetInt64(0)) == -1 {
|
||||||
|
return newNumber().SetInt64(0)
|
||||||
|
} else if n.Cmp(newNumber().SetInt64(0)) == 0 {
|
||||||
|
return newNumber().SetInt64(1)
|
||||||
|
}
|
||||||
|
result := newNumber().SetInt64(1)
|
||||||
|
for i := newNumber().SetInt64(2); i.Cmp(n) <= 0; i.Add(i, newNumber().SetInt64(1)) {
|
||||||
|
result.Mul(result, i)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func runFactorial(f factorial, stack stack, stacklevel int) (any, ArErr) {
|
func runFactorial(f factorial, stack stack, stacklevel int) (any, ArErr) {
|
||||||
val, err := runVal(f.value, stack, stacklevel+1)
|
val, err := runVal(f.value, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
switch val := val.(type) {
|
switch x := val.(type) {
|
||||||
case ArObject:
|
case number:
|
||||||
if callable, ok := val.obj["__factorial__"]; ok {
|
if !x.IsInt() {
|
||||||
return runCall(call{
|
return nil, ArErr{"Runtime Error", "cannot use factorial on non-integer", f.line, f.path, f.code, true}
|
||||||
Callable: callable,
|
}
|
||||||
Args: []any{},
|
if x.Cmp(newNumber().SetInt64(0)) == -1 {
|
||||||
Code: f.code,
|
return nil, ArErr{"Runtime Error", "cannot use factorial on negative number", f.line, f.path, f.code, true}
|
||||||
Line: f.line,
|
}
|
||||||
Path: f.path,
|
return fact(x), ArErr{}
|
||||||
}, stack, stacklevel)
|
default:
|
||||||
}
|
return nil, ArErr{"Runtime Error", "cannot use factorial on non-number of type '" + typeof(val) + "'", f.line, f.path, f.code, true}
|
||||||
}
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "TypeError",
|
|
||||||
message: "factorial not defined for type",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
193
src/file.go
193
src/file.go
@@ -5,80 +5,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/gabriel-vasile/mimetype"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
@@ -88,15 +21,6 @@ func readtext(file *os.File) (string, error) {
|
|||||||
return buf.String(), nil
|
return buf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readbinary(file *os.File) ([]byte, error) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
_, err := io.Copy(&buf, file)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ArRead(args ...any) (any, ArErr) {
|
func ArRead(args ...any) (any, ArErr) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "read takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
|
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "read takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
|
||||||
@@ -110,18 +34,6 @@ 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}
|
||||||
}
|
}
|
||||||
|
|
||||||
fileInfo, err := os.Stat(filename)
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "File does not exist: " + filename, EXISTS: true}
|
|
||||||
} else {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
} else if fileInfo.Mode().IsDir() {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "path goes to a directory, not a file: " + filename, EXISTS: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Map(anymap{
|
return Map(anymap{
|
||||||
"text": builtinFunc{"text", func(...any) (any, ArErr) {
|
"text": builtinFunc{"text", func(...any) (any, ArErr) {
|
||||||
text, err := readtext(file)
|
text, err := readtext(file)
|
||||||
@@ -135,78 +47,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)
|
return jsonparse(text), ArErr{}
|
||||||
}},
|
|
||||||
"contentType": builtinFunc{"contentType", func(...any) (any, ArErr) {
|
|
||||||
file.Seek(0, io.SeekStart)
|
|
||||||
mimetype, err := mimetype.DetectReader(file)
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return mimetype.String(), ArErr{}
|
|
||||||
}},
|
|
||||||
"buffer": builtinFunc{"buffer", func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) > 1 {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "buffer takes 0 or 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
|
|
||||||
}
|
|
||||||
if len(args) == 1 {
|
|
||||||
if typeof(args[0]) != "number" {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "buffer takes a number not type '" + typeof(args[0]) + "'", EXISTS: true}
|
|
||||||
}
|
|
||||||
size, err := numberToInt64(args[0].(ArObject))
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
buf := make([]byte, size)
|
|
||||||
n, err := file.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return ArBuffer(buf[:n]), ArErr{}
|
|
||||||
}
|
|
||||||
bytes, err := readbinary(file)
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return ArBuffer(bytes), ArErr{}
|
|
||||||
}},
|
|
||||||
"seek": builtinFunc{"seek", func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "seek takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
|
|
||||||
}
|
|
||||||
if typeof(args[0]) != "number" {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "seek takes a number not type '" + typeof(args[0]) + "'", EXISTS: true}
|
|
||||||
}
|
|
||||||
offset, Err := numberToInt64(args[0].(ArObject))
|
|
||||||
if Err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: Err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
_, err := file.Seek(offset, io.SeekStart)
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
|
||||||
}},
|
|
||||||
"size": builtinFunc{"size", func(...any) (any, ArErr) {
|
|
||||||
info, err := file.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return Number(info.Size()), ArErr{}
|
|
||||||
}},
|
|
||||||
"ModTime": builtinFunc{"ModTime", func(...any) (any, ArErr) {
|
|
||||||
info, err := file.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return ArTimeClass(info.ModTime()), ArErr{}
|
|
||||||
}},
|
|
||||||
"close": builtinFunc{"close", func(...any) (any, ArErr) {
|
|
||||||
err := file.Close()
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
|
||||||
}},
|
}},
|
||||||
}), ArErr{}
|
}), ArErr{}
|
||||||
}
|
}
|
||||||
@@ -232,25 +73,7 @@ func ArWrite(args ...any) (any, ArErr) {
|
|||||||
if typeof(args[0]) != "string" {
|
if typeof(args[0]) != "string" {
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "text takes a string not type '" + typeof(args[0]) + "'", EXISTS: true}
|
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "text takes a string not type '" + typeof(args[0]) + "'", EXISTS: true}
|
||||||
}
|
}
|
||||||
args[0] = ArValidToAny(args[0])
|
file.Write([]byte(args[0].(string)))
|
||||||
_, err = file.Write([]byte(args[0].(string)))
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
|
||||||
}},
|
|
||||||
"buffer": builtinFunc{"buffer", func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "buffer takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
|
|
||||||
}
|
|
||||||
if typeof(args[0]) != "buffer" {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "buffer takes a buffer not type '" + typeof(args[0]) + "'", EXISTS: true}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
_, err = file.Write(args[0].([]byte))
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}},
|
}},
|
||||||
"json": builtinFunc{"json", func(args ...any) (any, ArErr) {
|
"json": builtinFunc{"json", func(args ...any) (any, ArErr) {
|
||||||
@@ -261,17 +84,7 @@ func ArWrite(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}
|
||||||
}
|
}
|
||||||
_, err = file.Write([]byte(jsonstr))
|
file.Write([]byte(jsonstr))
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
|
||||||
}},
|
|
||||||
"close": builtinFunc{"close", func(...any) (any, ArErr) {
|
|
||||||
err := file.Close()
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}},
|
}},
|
||||||
}), ArErr{}
|
}), ArErr{}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func parseForLoop(code UNPARSEcode, index int, codelines []UNPARSEcode) (forLoop
|
|||||||
innertotalstep += stepstep - 1
|
innertotalstep += stepstep - 1
|
||||||
stepval = stepval_
|
stepval = stepval_
|
||||||
} else {
|
} else {
|
||||||
stepval = _one_Number
|
stepval = newNumber().SetInt64(1)
|
||||||
}
|
}
|
||||||
to := strings.TrimSpace(valsplit[0])
|
to := strings.TrimSpace(valsplit[0])
|
||||||
toval, worked, err, tostep := translateVal(UNPARSEcode{code: to, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0)
|
toval, worked, err, tostep := translateVal(UNPARSEcode{code: to, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0)
|
||||||
@@ -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, 3)
|
bodyval, worked, err, bodystep := translateVal(UNPARSEcode{code: body, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 1)
|
||||||
if !worked {
|
if !worked {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
return forLoop{}, worked, err, bodystep
|
return forLoop{}, worked, err, bodystep
|
||||||
@@ -83,7 +83,7 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if typeof(fromval) != "number" {
|
if typeof(fromval) != "number" {
|
||||||
return nil, ArErr{"Type Error", "for loop from value must be a number", loop.line, loop.path, loop.code, true}
|
return nil, ArErr{"Type Error", "for loop from value must be a number", loop.line, loop.path, loop.code, true}
|
||||||
}
|
}
|
||||||
from := fromval.(ArObject)
|
from := fromval.(number)
|
||||||
toval, err := runVal(loop.to, stack, stacklevel+1)
|
toval, err := runVal(loop.to, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -91,7 +91,7 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if typeof(toval) != "number" {
|
if typeof(toval) != "number" {
|
||||||
return nil, ArErr{"Type Error", "for loop to value must be a number", loop.line, loop.path, loop.code, true}
|
return nil, ArErr{"Type Error", "for loop to value must be a number", loop.line, loop.path, loop.code, true}
|
||||||
}
|
}
|
||||||
to := toval.(ArObject)
|
to := toval.(number)
|
||||||
stepval, err := runVal(loop.step, stack, stacklevel+1)
|
stepval, err := runVal(loop.step, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -99,16 +99,11 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if typeof(stepval) != "number" {
|
if typeof(stepval) != "number" {
|
||||||
return nil, ArErr{"Type Error", "for loop step value must be a number", loop.line, loop.path, loop.code, true}
|
return nil, ArErr{"Type Error", "for loop step value must be a number", loop.line, loop.path, loop.code, true}
|
||||||
}
|
}
|
||||||
step := stepval.(ArObject)
|
step := stepval.(number)
|
||||||
if isNumberInt64(from) && isNumberInt64(to) && isNumberInt64(step) {
|
for i := newNumber().Set(from); i.Cmp(to) == -1; i = i.Add(i, step) {
|
||||||
i, _ := numberToInt64(from)
|
resp, err := runVal(loop.body, append(stack, Map(anymap{
|
||||||
to_, _ := numberToInt64(to)
|
loop.variable: newNumber().Set(i),
|
||||||
step_, _ := numberToInt64(step)
|
})), stacklevel+1)
|
||||||
layer := anymap{}
|
|
||||||
stacks := append(stack, Map(layer))
|
|
||||||
for i < to_ {
|
|
||||||
layer[loop.variable] = Number(i)
|
|
||||||
resp, err := runVal(loop.body, stacks, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -118,58 +113,7 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
case Break:
|
case Break:
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
case Continue:
|
case Continue:
|
||||||
}
|
continue
|
||||||
i += step_
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
|
||||||
}
|
|
||||||
i := from
|
|
||||||
direction_obj, err := CompareObjects(step, _zero_Number)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
currentDirection_obj, err := CompareObjects(to, i)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
currentDirection, error := numberToInt64(currentDirection_obj)
|
|
||||||
if error != nil {
|
|
||||||
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
|
|
||||||
}
|
|
||||||
direction, error := numberToInt64(direction_obj)
|
|
||||||
if error != nil {
|
|
||||||
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
|
|
||||||
}
|
|
||||||
layer := anymap{}
|
|
||||||
stacks := append(stack, Map(layer))
|
|
||||||
for currentDirection == direction {
|
|
||||||
layer[loop.variable] = i
|
|
||||||
resp, err := runVal(loop.body, stacks, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch x := resp.(type) {
|
|
||||||
case Return:
|
|
||||||
return x, ArErr{}
|
|
||||||
case Break:
|
|
||||||
return nil, ArErr{}
|
|
||||||
case Continue:
|
|
||||||
}
|
|
||||||
i, err = AddObjects(i, step)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
currentDirection_obj, err = CompareObjects(to, i)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
currentDirection, error = numberToInt64(currentDirection_obj)
|
|
||||||
if error != nil {
|
|
||||||
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
|
|
||||||
}
|
|
||||||
direction, error = numberToInt64(direction_obj)
|
|
||||||
if error != nil {
|
|
||||||
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
|
|||||||
@@ -15,11 +15,10 @@ var indexGetCompile = makeRegex(`(.|\n)+\[(.|\n)+\]( *)`)
|
|||||||
|
|
||||||
type ArMapGet struct {
|
type ArMapGet struct {
|
||||||
VAL any
|
VAL any
|
||||||
Args []any
|
args []any
|
||||||
IncludeConstuctors bool
|
line int
|
||||||
Line int
|
code string
|
||||||
Code string
|
path string
|
||||||
Path string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
||||||
@@ -29,33 +28,36 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
switch m := resp.(type) {
|
switch m := resp.(type) {
|
||||||
case ArObject:
|
case ArObject:
|
||||||
if r.IncludeConstuctors {
|
if _, ok := m.obj["__getindex__"]; ok {
|
||||||
if obj, ok := m.obj[r.Args[0]]; ok {
|
callable := m.obj["__getindex__"]
|
||||||
return obj, ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if callable, ok := m.obj["__getindex__"]; ok {
|
|
||||||
resp, err := runCall(call{
|
resp, err := runCall(call{
|
||||||
Callable: callable,
|
callable: callable,
|
||||||
Args: r.Args,
|
args: r.args,
|
||||||
Line: r.Line,
|
line: r.line,
|
||||||
Path: r.Path,
|
path: r.path,
|
||||||
Code: r.Code,
|
code: r.code,
|
||||||
}, stack, stacklevel+1)
|
}, stack, stacklevel+1)
|
||||||
return resp, err
|
if !err.EXISTS {
|
||||||
|
return resp, ArErr{}
|
||||||
|
}
|
||||||
|
if len(r.args) == 1 && !isUnhashable(r.args[0]) {
|
||||||
|
if _, ok := m.obj[r.args[0]]; ok {
|
||||||
|
return m.obj[r.args[0]], ArErr{}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := runVal(r.Args[0], stack, stacklevel+1)
|
key, err := runVal(r.args[0], stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"TypeError",
|
"TypeError",
|
||||||
"cannot read " + anyToArgon(key, true, true, 3, 0, false, 0) + " from type '" + typeof(resp) + "'",
|
"cannot read " + anyToArgon(key, true, true, 3, 0, false, 0) + " from type '" + typeof(resp) + "'",
|
||||||
r.Line,
|
r.line,
|
||||||
r.Path,
|
r.path,
|
||||||
r.Code,
|
r.code,
|
||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,7 +75,7 @@ func mapGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapGet
|
|||||||
if !worked {
|
if !worked {
|
||||||
return ArMapGet{}, false, err, i
|
return ArMapGet{}, false, err, i
|
||||||
}
|
}
|
||||||
return ArMapGet{resp, []any{key}, true, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
return ArMapGet{resp, []any{key}, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func isIndexGet(code UNPARSEcode) bool {
|
func isIndexGet(code UNPARSEcode) bool {
|
||||||
@@ -111,7 +113,7 @@ func indexGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapG
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return ArMapGet{tival, args, false, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
return ArMapGet{tival, args, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
||||||
}
|
}
|
||||||
return ArMapGet{}, false, ArErr{
|
return ArMapGet{}, false, ArErr{
|
||||||
"Syntax Error",
|
"Syntax Error",
|
||||||
@@ -123,10 +125,19 @@ func indexGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapG
|
|||||||
}, 1
|
}, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hashabletypes = []string{
|
||||||
|
"number",
|
||||||
|
"string",
|
||||||
|
"bool",
|
||||||
|
"null",
|
||||||
|
}
|
||||||
|
|
||||||
func isUnhashable(val any) bool {
|
func isUnhashable(val any) bool {
|
||||||
switch val.(type) {
|
keytype := typeof(val)
|
||||||
case int64, float64, string, bool, nil:
|
for _, v := range hashabletypes {
|
||||||
|
if v == keytype {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ 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, "("):])
|
||||||
@@ -51,7 +50,8 @@ func parseIfStatement(code UNPARSEcode, index int, codeline []UNPARSEcode) (ifst
|
|||||||
},
|
},
|
||||||
i,
|
i,
|
||||||
codeline,
|
codeline,
|
||||||
0)
|
0,
|
||||||
|
)
|
||||||
if err.EXISTS || !worked {
|
if err.EXISTS || !worked {
|
||||||
if j == 1 {
|
if j == 1 {
|
||||||
return ifstatement{}, worked, err, step
|
return ifstatement{}, worked, err, step
|
||||||
@@ -70,7 +70,7 @@ func parseIfStatement(code UNPARSEcode, index int, codeline []UNPARSEcode) (ifst
|
|||||||
},
|
},
|
||||||
i,
|
i,
|
||||||
codeline,
|
codeline,
|
||||||
3,
|
2,
|
||||||
)
|
)
|
||||||
if err.EXISTS || !worked {
|
if err.EXISTS || !worked {
|
||||||
return ifstatement{}, worked, err, step
|
return ifstatement{}, worked, err, step
|
||||||
@@ -99,7 +99,7 @@ func parseIfStatement(code UNPARSEcode, index int, codeline []UNPARSEcode) (ifst
|
|||||||
},
|
},
|
||||||
i,
|
i,
|
||||||
codeline,
|
codeline,
|
||||||
3,
|
2,
|
||||||
)
|
)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return ifstatement{}, false, err, step
|
return ifstatement{}, false, err, step
|
||||||
|
|||||||
183
src/import.go
183
src/import.go
@@ -2,27 +2,30 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
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"
|
|
||||||
|
|
||||||
func FileExists(filename string) bool {
|
func FileExists(filename string) bool {
|
||||||
if info, err := os.Stat(filename); err == nil && !info.IsDir() {
|
if _, err := os.Stat(filename); err == nil {
|
||||||
return true
|
return true
|
||||||
}
|
|
||||||
|
} else if errors.Is(err, os.ErrNotExist) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func readFile(path string) ([]UNPARSEcode, error) {
|
func readFile(path string) []UNPARSEcode {
|
||||||
file, err := os.Open(path)
|
file, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
log.Fatal(err)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
@@ -37,72 +40,33 @@ func readFile(path string) ([]UNPARSEcode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
return nil, err
|
log.Fatal(err)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return output, nil
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
type translatedImport struct {
|
func importMod(realpath string, origin string, main bool, global ArObject) (ArObject, ArErr) {
|
||||||
translated []any
|
return ArObject{}, ArErr{
|
||||||
p string
|
TYPE: "Import Error",
|
||||||
path string
|
message: "importing in WASM is currently not supported",
|
||||||
origin string
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
var runTranslatedImport func(translatedImport, ArObject, bool) (ArObject, ArErr)
|
|
||||||
var ex string
|
|
||||||
var exc string
|
|
||||||
var exc_dir string
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
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{}
|
|
||||||
withoutarfile := []string{}
|
|
||||||
if len(Args) > 1 {
|
|
||||||
withoutarfile = Args[1:]
|
|
||||||
}
|
|
||||||
for _, arg := range withoutarfile {
|
|
||||||
ArgsArArray = append(ArgsArArray, arg)
|
|
||||||
}
|
|
||||||
local := newscope()
|
|
||||||
localvars := Map(anymap{
|
|
||||||
"program": Map(anymap{
|
|
||||||
"args": ArArray(ArgsArArray),
|
|
||||||
"origin": ArString(translatedImport.origin),
|
|
||||||
"cwd": ArString(ex),
|
|
||||||
"exc": ArString(exc),
|
|
||||||
"file": Map(anymap{
|
|
||||||
"name": ArString(filepath.Base(translatedImport.p)),
|
|
||||||
"path": ArString(translatedImport.p),
|
|
||||||
}),
|
|
||||||
"main": main,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
imported[translatedImport.p] = local
|
|
||||||
_, runimeErr := run(translatedImport.translated, stack{global, localvars, local})
|
|
||||||
if runimeErr.EXISTS {
|
|
||||||
return ArObject{}, runimeErr
|
|
||||||
}
|
|
||||||
return local, ArErr{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func translateImport(realpath string, origin string, topLevelOnly bool) (translatedImport, ArErr) {
|
|
||||||
extention := filepath.Ext(realpath)
|
extention := filepath.Ext(realpath)
|
||||||
path := realpath
|
path := realpath
|
||||||
if extention == "" {
|
if extention == "" {
|
||||||
path += ".ar"
|
path += ".ar"
|
||||||
}
|
}
|
||||||
|
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)
|
isABS := filepath.IsAbs(path)
|
||||||
var pathsToTest []string
|
var pathsToTest []string
|
||||||
if isABS {
|
if isABS {
|
||||||
@@ -112,26 +76,18 @@ func translateImport(realpath string, origin string, topLevelOnly bool) (transla
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pathsToTest = []string{
|
pathsToTest = []string{
|
||||||
filepath.Join(exc_dir, path),
|
filepath.Join(origin, realpath, "init.ar"),
|
||||||
filepath.Join(exc_dir, realpath, "init.ar"),
|
filepath.Join(origin, path),
|
||||||
filepath.Join(exc_dir, modules_folder, path),
|
filepath.Join(origin, "modules", path),
|
||||||
filepath.Join(exc_dir, modules_folder, realpath, "init.ar"),
|
filepath.Join(origin, "modules", realpath, "init.ar"),
|
||||||
}
|
filepath.Join(ex, path),
|
||||||
var currentPath string = origin
|
filepath.Join(ex, "modules", realpath, "init.ar"),
|
||||||
var oldPath string = ""
|
filepath.Join(ex, "modules", path),
|
||||||
for currentPath != oldPath {
|
filepath.Join(executable, "modules", realpath, "init.ar"),
|
||||||
pathsToTest = append(pathsToTest,
|
filepath.Join(executable, "modules", path),
|
||||||
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 p string
|
||||||
var found bool
|
var found bool
|
||||||
for _, p = range pathsToTest {
|
for _, p = range pathsToTest {
|
||||||
@@ -142,26 +98,57 @@ func translateImport(realpath string, origin string, topLevelOnly bool) (transla
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
return translatedImport{}, ArErr{TYPE: "Import Error", message: "File does not exist: " + path, EXISTS: true}
|
return ArObject{}, ArErr{TYPE: "Import Error", message: "File does not exist: " + realpath, EXISTS: true}
|
||||||
} else if importing[p] {
|
} else if importing[p] {
|
||||||
return translatedImport{}, ArErr{TYPE: "Import Error", message: "Circular import: " + path, EXISTS: true}
|
return ArObject{}, ArErr{TYPE: "Import Error", message: "Circular import: " + realpath, EXISTS: true}
|
||||||
} else if _, ok := translatedImports[p]; ok {
|
} else if _, ok := imported[p]; ok {
|
||||||
return translatedImports[p], ArErr{}
|
return imported[p], ArErr{}
|
||||||
}
|
}
|
||||||
importing[p] = true
|
importing[p] = true
|
||||||
codelines, err := readFile(p)
|
codelines := 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)
|
translated, translationerr := translate(codelines)
|
||||||
importing[p] = false
|
|
||||||
|
|
||||||
if translationerr.EXISTS {
|
if translationerr.EXISTS {
|
||||||
return translatedImport{}, translationerr
|
return ArObject{}, translationerr
|
||||||
}
|
}
|
||||||
|
ArgsArArray := []any{}
|
||||||
translatedImports[p] = translatedImport{translated, p, path, origin}
|
withoutarfile := []string{}
|
||||||
return translatedImports[p], ArErr{}
|
if len(Args) > 1 {
|
||||||
|
withoutarfile = Args[1:]
|
||||||
|
}
|
||||||
|
for _, arg := range withoutarfile {
|
||||||
|
ArgsArArray = append(ArgsArArray, arg)
|
||||||
|
}
|
||||||
|
global := newscope()
|
||||||
|
localvars := Map(anymap{
|
||||||
|
"program": Map(anymap{
|
||||||
|
"args": ArArray(ArgsArArray),
|
||||||
|
"origin": 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(p), false)
|
||||||
|
}},
|
||||||
|
"cwd": ex,
|
||||||
|
"exc": exc,
|
||||||
|
"file": Map(anymap{
|
||||||
|
"name": filepath.Base(p),
|
||||||
|
"path": p,
|
||||||
|
}),
|
||||||
|
"main": main,
|
||||||
|
"scope": global,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
_, runimeErr := ThrowOnNonLoop(run(translated, stack{vars, localvars, global}))
|
||||||
|
importing[p] = false
|
||||||
|
if runimeErr.EXISTS {
|
||||||
|
return ArObject{}, runimeErr
|
||||||
|
}
|
||||||
|
imported[p] = global
|
||||||
|
return global, ArErr{}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
package main
|
|
||||||
71
src/input.go
71
src/input.go
@@ -2,35 +2,25 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
|
"syscall/js"
|
||||||
|
|
||||||
"github.com/chzyer/readline"
|
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tempFilePath = os.TempDir() + "/argon_input_history.tmp"
|
func input(args ...any) string {
|
||||||
|
|
||||||
func input(args ...any) (string, error) {
|
|
||||||
output := []any{}
|
output := []any{}
|
||||||
for i := 0; i < len(args); i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
|
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
|
||||||
|
if i != len(args)-1 {
|
||||||
|
output = append(output, " ")
|
||||||
}
|
}
|
||||||
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()
|
text := fmt.Sprint(output...)
|
||||||
line, err := rl.Readline()
|
fmt.Print(text)
|
||||||
if err != nil { // io.EOF or other error
|
inputData := js.Global().Get("getInput").Invoke(fmt.Sprint(output...)).String()
|
||||||
return "", err
|
fmt.Println(inputData)
|
||||||
}
|
return (inputData)
|
||||||
return line, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPassword(args ...any) (string, error) {
|
func getPassword(args ...any) (string, error) {
|
||||||
@@ -38,25 +28,36 @@ func getPassword(args ...any) (string, error) {
|
|||||||
for i := 0; i < len(args); i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
|
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
|
||||||
}
|
}
|
||||||
message := fmt.Sprint(output...)
|
fmt.Print(output...)
|
||||||
rl, err := readline.NewEx(&readline.Config{
|
password := []byte{}
|
||||||
Prompt: message,
|
|
||||||
MaskRune: '*',
|
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
|
||||||
EnableMask: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to create readline instance: %v", err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer rl.Close()
|
defer term.Restore(int(os.Stdin.Fd()), oldState)
|
||||||
line, err := rl.Readline()
|
|
||||||
if err != nil { // io.EOF or other error
|
for {
|
||||||
|
char := make([]byte, 1)
|
||||||
|
_, err := os.Stdin.Read(char)
|
||||||
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return line, nil
|
if char[0] == 3 || char[0] == 4 {
|
||||||
}
|
return "", fmt.Errorf("keyboard interupt")
|
||||||
|
} else if char[0] == '\r' || char[0] == '\n' {
|
||||||
func pause() {
|
|
||||||
fmt.Print("Press Enter to continue...")
|
|
||||||
term.ReadPassword(int(os.Stdin.Fd()))
|
|
||||||
fmt.Println()
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
79
src/json.go
79
src/json.go
@@ -3,7 +3,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertToArgon(obj any) any {
|
func convertToArgon(obj any) any {
|
||||||
@@ -20,9 +22,9 @@ func convertToArgon(obj any) any {
|
|||||||
}
|
}
|
||||||
return ArArray(x)
|
return ArArray(x)
|
||||||
case string:
|
case string:
|
||||||
return ArString(x)
|
return x
|
||||||
case float64:
|
case float64:
|
||||||
return Number(x)
|
return newNumber().SetFloat64(x)
|
||||||
case bool:
|
case bool:
|
||||||
return x
|
return x
|
||||||
case nil:
|
case nil:
|
||||||
@@ -31,40 +33,45 @@ func convertToArgon(obj any) any {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonparse(str string) (any, ArErr) {
|
func jsonparse(str string) any {
|
||||||
var jsonMap any
|
var jsonMap any
|
||||||
var err = json.Unmarshal([]byte(str), &jsonMap)
|
json.Unmarshal([]byte(str), &jsonMap)
|
||||||
if err != nil {
|
return convertToArgon(jsonMap)
|
||||||
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return convertToArgon(jsonMap), ArErr{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonstringify(obj any, level int64) (string, error) {
|
func jsonstringify(obj any, level int) (string, error) {
|
||||||
if level > 100 {
|
if level > 100 {
|
||||||
return "", errors.New("json stringify error: too many levels")
|
return "", errors.New("json stringify error: too many levels")
|
||||||
}
|
}
|
||||||
|
output := []string{}
|
||||||
|
obj = ArValidToAny(obj)
|
||||||
switch x := obj.(type) {
|
switch x := obj.(type) {
|
||||||
case ArObject:
|
case ArObject:
|
||||||
if callable, ok := x.obj["__json__"]; ok {
|
for key, value := range x.obj {
|
||||||
val, err := runCall(
|
str, err := jsonstringify(value, level+1)
|
||||||
call{
|
if err != nil {
|
||||||
Callable: callable,
|
return "", err
|
||||||
Args: []any{Int64ToNumber(level)},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if err.EXISTS {
|
|
||||||
return "", errors.New(err.message)
|
|
||||||
}
|
}
|
||||||
val = ArValidToAny(val)
|
output = append(output, ""+strconv.Quote(anyToArgon(key, false, true, 3, 0, false, 0))+": "+str)
|
||||||
if x, ok := val.(string); ok {
|
|
||||||
return x, nil
|
|
||||||
} else {
|
|
||||||
return "", errors.New("json stringify error: __json__ must return a string")
|
|
||||||
}
|
}
|
||||||
|
return "{" + strings.Join(output, ", ") + "}", nil
|
||||||
|
case []any:
|
||||||
|
for _, value := range x {
|
||||||
|
str, err := jsonstringify(value, level+1)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
|
output = append(output, str)
|
||||||
|
}
|
||||||
|
return "[" + strings.Join(output, ", ") + "]", nil
|
||||||
|
case string:
|
||||||
|
return strconv.Quote(x), nil
|
||||||
|
case number:
|
||||||
|
num, _ := x.Float64()
|
||||||
|
if math.IsNaN(num) || math.IsInf(num, 0) {
|
||||||
|
return "null", nil
|
||||||
|
}
|
||||||
|
return numberToString(x, false), nil
|
||||||
case bool:
|
case bool:
|
||||||
return strconv.FormatBool(x), nil
|
return strconv.FormatBool(x), nil
|
||||||
case nil:
|
case nil:
|
||||||
@@ -82,28 +89,16 @@ var ArJSON = Map(anymap{
|
|||||||
if typeof(args[0]) != "string" {
|
if typeof(args[0]) != "string" {
|
||||||
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])
|
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) != 1 && len(args) != 2 {
|
if len(args) == 0 {
|
||||||
return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 or 2 arguments", EXISTS: true}
|
return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 argument", EXISTS: true}
|
||||||
}
|
}
|
||||||
var level int64 = 0
|
str, err := jsonstringify(args[0], 0)
|
||||||
if len(args) == 2 {
|
|
||||||
if typeof(args[1]) != "number" {
|
|
||||||
return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes a number not a '" + typeof(args[1]) + "'", EXISTS: true}
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
level, err = numberToInt64(args[1].(ArObject))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||||
}
|
}
|
||||||
}
|
return str, ArErr{}
|
||||||
str, err := jsonstringify(args[0], level)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return ArString(str), ArErr{}
|
|
||||||
}},
|
}},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var returnCompile = makeRegex(`( *)return(( +)(.|\n)+)?`)
|
var returnCompile = makeRegex(`( *)return( +)(.|\n)+`)
|
||||||
var breakCompile = makeRegex(`( *)break( *)`)
|
var breakCompile = makeRegex(`( *)break( *)`)
|
||||||
var continueCompile = makeRegex(`( *)continue( *)`)
|
var continueCompile = makeRegex(`( *)continue( *)`)
|
||||||
|
|
||||||
@@ -45,17 +45,12 @@ func isContinue(code UNPARSEcode) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseReturn(code UNPARSEcode, index int, codeline []UNPARSEcode) (CallReturn, bool, ArErr, int) {
|
func parseReturn(code UNPARSEcode, index int, codeline []UNPARSEcode) (CallReturn, bool, ArErr, int) {
|
||||||
val := strings.TrimSpace(code.code)[6:]
|
resp, worked, err, i := translateVal(UNPARSEcode{
|
||||||
var resp any
|
code: strings.TrimSpace(code.code)[6:],
|
||||||
var worked, err, i = true, ArErr{}, 1
|
|
||||||
if val != "" {
|
|
||||||
resp, worked, err, i = translateVal(UNPARSEcode{
|
|
||||||
code: val,
|
|
||||||
realcode: code.realcode,
|
realcode: code.realcode,
|
||||||
line: code.line,
|
line: code.line,
|
||||||
path: code.path,
|
path: code.path,
|
||||||
}, index, codeline, 1)
|
}, index, codeline, 1)
|
||||||
}
|
|
||||||
return CallReturn{
|
return CallReturn{
|
||||||
value: resp,
|
value: resp,
|
||||||
line: code.line,
|
line: code.line,
|
||||||
@@ -71,7 +66,6 @@ func runReturn(code CallReturn, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
v = openReturn(v)
|
|
||||||
val = v
|
val = v
|
||||||
}
|
}
|
||||||
return Return{
|
return Return{
|
||||||
@@ -82,19 +76,6 @@ func runReturn(code CallReturn, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}, ArErr{}
|
}, ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func translateThrowOnNonLoop(val any) ArErr {
|
|
||||||
switch x := val.(type) {
|
|
||||||
case Break:
|
|
||||||
return ArErr{"Break Error", "break can only be used in loops", x.line, x.path, x.code, true}
|
|
||||||
case Continue:
|
|
||||||
return ArErr{"Continue Error", "continue can only be used in loops", x.line, x.path, x.code, true}
|
|
||||||
case CallReturn:
|
|
||||||
return ArErr{"Return Error", "return can only be used in do wraps", x.line, x.path, x.code, true}
|
|
||||||
default:
|
|
||||||
return ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func openReturn(resp any) any {
|
func openReturn(resp any) any {
|
||||||
switch x := resp.(type) {
|
switch x := resp.(type) {
|
||||||
case Return:
|
case Return:
|
||||||
|
|||||||
@@ -5,26 +5,19 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
var N = Number(1e6)
|
var N = newNumber().SetInt64(1e6)
|
||||||
|
|
||||||
func Ln(x ArObject) (any, ArErr) {
|
func Ln(x number) number {
|
||||||
var output any = Number(1)
|
output := newNumber()
|
||||||
var err ArErr
|
output.SetInt64(1)
|
||||||
output, err = runOperation(
|
output.Quo(output, N)
|
||||||
operationType{
|
|
||||||
operation: 15,
|
|
||||||
values: []any{x},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
n1, _ := x_rational.Float64()
|
n1, _ := x.Float64()
|
||||||
n2, _ := output.Float64()
|
n2, _ := output.Float64()
|
||||||
output = newNumber().SetFloat64(math.Pow(n1, n2))
|
output = newNumber().SetFloat64(math.Pow(n1, n2))
|
||||||
|
if output == nil {
|
||||||
|
output = infinity
|
||||||
|
}
|
||||||
output.Sub(output, newNumber().SetInt64(1))
|
output.Sub(output, newNumber().SetInt64(1))
|
||||||
output.Mul(output, N)
|
output.Mul(output, N)
|
||||||
return output
|
return output
|
||||||
@@ -44,11 +37,10 @@ func ArgonLn(a ...any) (any, ArErr) {
|
|||||||
return nil, ArErr{TYPE: "Runtime Error", message: "ln takes a positive number",
|
return nil, ArErr{TYPE: "Runtime Error", message: "ln takes a positive number",
|
||||||
EXISTS: true}
|
EXISTS: true}
|
||||||
}
|
}
|
||||||
return Ln(x)
|
return Ln(x), ArErr{}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var __ln10, _ = Ln(Number(10))
|
var __ln10 = Ln(newNumber().SetInt64(10))
|
||||||
|
|
||||||
func ArgonLog(a ...any) (any, ArErr) {
|
func ArgonLog(a ...any) (any, ArErr) {
|
||||||
if len(a) != 1 {
|
if len(a) != 1 {
|
||||||
@@ -64,7 +56,7 @@ func ArgonLog(a ...any) (any, ArErr) {
|
|||||||
return nil, ArErr{TYPE: "Runtime Error", message: "log takes a positive number",
|
return nil, ArErr{TYPE: "Runtime Error", message: "log takes a positive number",
|
||||||
EXISTS: true}
|
EXISTS: true}
|
||||||
}
|
}
|
||||||
return Ln(x).Quo(Ln(x), __ln10)
|
return Ln(x).Quo(Ln(x), __ln10), ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ArgonLogN(a ...any) (any, ArErr) {
|
func ArgonLogN(a ...any) (any, ArErr) {
|
||||||
|
|||||||
45
src/main.go
45
src/main.go
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"syscall/js"
|
||||||
)
|
)
|
||||||
|
|
||||||
// args without the program path
|
// args without the program path
|
||||||
@@ -10,23 +11,15 @@ var Args = os.Args[1:]
|
|||||||
|
|
||||||
type stack = []ArObject
|
type stack = []ArObject
|
||||||
|
|
||||||
const VERSION = "3.1.0 oop numbers beta 1"
|
|
||||||
const VERSION_NUM = 7
|
|
||||||
|
|
||||||
func newscope() ArObject {
|
func newscope() ArObject {
|
||||||
return Map(anymap{})
|
return Map(anymap{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
debugInit()
|
c := make(chan ArObject)
|
||||||
|
|
||||||
if !debug {
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Println("There was a fundamental error in argon v" + VERSION + " that caused it to crash.")
|
fmt.Println("There was a fundamental error in argon v3 that caused it to crash.")
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("website:", website)
|
|
||||||
fmt.Println("docs:", docs)
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
if fork {
|
if fork {
|
||||||
fmt.Println("This is a fork of Open-Argon. Please report this to the fork's maintainer.")
|
fmt.Println("This is a fork of Open-Argon. Please report this to the fork's maintainer.")
|
||||||
@@ -44,26 +37,26 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
initRandom()
|
||||||
garbageCollect()
|
garbageCollect()
|
||||||
global := makeGlobal()
|
obj := js.Global().Get("Object").New()
|
||||||
if len(Args) == 0 {
|
obj.Set("eval", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
shell(global)
|
code := ""
|
||||||
os.Exit(0)
|
allowDocument := false
|
||||||
|
if len(args) >= 1 {
|
||||||
|
code = args[0].String()
|
||||||
}
|
}
|
||||||
ex, e := os.Getwd()
|
if len(args) >= 2 {
|
||||||
if e != nil {
|
allowDocument = args[1].Bool()
|
||||||
panic(e)
|
|
||||||
}
|
}
|
||||||
translated, err := translateImport(Args[0], ex, true)
|
val, err := wasmRun(code, allowDocument)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
panicErr(err)
|
panicErr(err)
|
||||||
os.Exit(1)
|
return js.Null()
|
||||||
}
|
}
|
||||||
_, runimeErr := runTranslatedImport(translated, global, true)
|
|
||||||
if runimeErr.EXISTS {
|
return js.ValueOf(argonToJsValid(val))
|
||||||
panicErr(runimeErr)
|
}))
|
||||||
os.Exit(1)
|
js.Global().Set("Ar", obj)
|
||||||
}
|
<-c
|
||||||
threadChan.Wait()
|
|
||||||
}
|
}
|
||||||
|
|||||||
407
src/map.go
407
src/map.go
@@ -6,10 +6,10 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var mapCompiled = makeRegex(`( )*{( |\n)*(((.|\n)+)(,(.|\n)+)*)?( |\n)*}( )*`)
|
var mapCompiled = makeRegex(`( *)\{(((( *).+( *):( *).+( *))|(` + spacelessVariable + `))(( *)\,(( *).+( *):( *).+( *))|(` + spacelessVariable + `)))*\}( *)`)
|
||||||
|
|
||||||
type createMap struct {
|
type createMap struct {
|
||||||
body [][2]any
|
body anymap
|
||||||
code string
|
code string
|
||||||
line int
|
line int
|
||||||
path string
|
path string
|
||||||
@@ -19,112 +19,21 @@ func isMap(code UNPARSEcode) bool {
|
|||||||
return mapCompiled.MatchString(code.code)
|
return mapCompiled.MatchString(code.code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCreateMap(m createMap, stack stack, stacklevel int) (any, ArErr) {
|
func parseMap(code UNPARSEcode) (any, UNPARSEcode) {
|
||||||
var body = m.body
|
trimmed := strings.Trim(code.code, " ")
|
||||||
var newmap = anymap{}
|
|
||||||
for _, pair := range body {
|
|
||||||
key := pair[0]
|
|
||||||
val := pair[1]
|
|
||||||
keyVal, err := runVal(key, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keyVal = ArValidToAny(keyVal)
|
|
||||||
valVal, err := runVal(val, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if isUnhashable(keyVal) {
|
|
||||||
return nil, ArErr{
|
|
||||||
"Type Error",
|
|
||||||
"unhashable type: '" + typeof(keyVal) + "'",
|
|
||||||
m.line,
|
|
||||||
m.path,
|
|
||||||
m.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newmap[keyVal] = valVal
|
|
||||||
}
|
|
||||||
return Map(newmap), ArErr{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseMap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr, int) {
|
|
||||||
trimmed := strings.TrimSpace(code.code)
|
|
||||||
trimmed = trimmed[1 : len(trimmed)-1]
|
trimmed = trimmed[1 : len(trimmed)-1]
|
||||||
if len(trimmed) == 0 {
|
fmt.Println(trimmed)
|
||||||
return createMap{
|
return nil, UNPARSEcode{}
|
||||||
body: [][2]any{},
|
|
||||||
code: code.realcode,
|
|
||||||
line: code.line,
|
|
||||||
path: code.path,
|
|
||||||
}, true, ArErr{}, 1
|
|
||||||
}
|
|
||||||
var body [][2]any
|
|
||||||
var LookingAtKey bool = true
|
|
||||||
var current int
|
|
||||||
var currentKey any
|
|
||||||
var countIndex int = 1
|
|
||||||
for i := 0; i < len(trimmed); i++ {
|
|
||||||
var str string
|
|
||||||
if LookingAtKey {
|
|
||||||
if trimmed[i] != ':' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
str = trimmed[current:i]
|
|
||||||
} else {
|
|
||||||
if trimmed[i] != ',' && i != len(trimmed)-1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if i == len(trimmed)-1 {
|
|
||||||
str = trimmed[current:]
|
|
||||||
} else {
|
|
||||||
str = trimmed[current:i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var value any
|
|
||||||
if LookingAtKey && variableCompile.MatchString(str) {
|
|
||||||
value = strings.TrimSpace(str)
|
|
||||||
} else {
|
|
||||||
val1, worked, err, indexcounted := translateVal(UNPARSEcode{code: str, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0)
|
|
||||||
if !worked || err.EXISTS {
|
|
||||||
if i == len(trimmed)-1 {
|
|
||||||
return val1, worked, err, i
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
value = val1
|
|
||||||
countIndex += indexcounted - 1
|
|
||||||
}
|
|
||||||
if LookingAtKey {
|
|
||||||
currentKey = value
|
|
||||||
current = i + 1
|
|
||||||
LookingAtKey = false
|
|
||||||
} else {
|
|
||||||
body = append(body, [2]any{currentKey, value})
|
|
||||||
current = i + 1
|
|
||||||
LookingAtKey = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return createMap{
|
|
||||||
body: body,
|
|
||||||
code: code.realcode,
|
|
||||||
line: code.line,
|
|
||||||
path: code.path,
|
|
||||||
}, true, ArErr{}, countIndex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Map(m anymap) ArObject {
|
func Map(m anymap) ArObject {
|
||||||
var mutex = sync.RWMutex{}
|
var mutex = sync.RWMutex{}
|
||||||
var listenersMutex = sync.RWMutex{}
|
return ArObject{
|
||||||
var currentID uint32 = 0
|
|
||||||
listeners := map[any]map[uint32]any{}
|
|
||||||
obj := ArObject{
|
|
||||||
obj: anymap{
|
obj: anymap{
|
||||||
"__value__": m,
|
"__value__": m,
|
||||||
"__name__": "map",
|
"__name__": "map",
|
||||||
"get_value": builtinFunc{
|
"get": builtinFunc{
|
||||||
"get_value",
|
"get",
|
||||||
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{
|
||||||
@@ -170,29 +79,12 @@ func Map(m anymap) ArObject {
|
|||||||
return false, ArErr{}
|
return false, ArErr{}
|
||||||
}
|
}
|
||||||
mutex.RLock()
|
mutex.RLock()
|
||||||
if _, ok := m[key]; ok {
|
if _, ok := m[key]; !ok {
|
||||||
mutex.RUnlock()
|
|
||||||
return true, ArErr{}
|
|
||||||
}
|
|
||||||
for k := range m {
|
|
||||||
compare, err := runOperation(
|
|
||||||
operationType{
|
|
||||||
operation: 9,
|
|
||||||
values: []any{key, k},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if err.EXISTS {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if anyToBool(compare) {
|
|
||||||
mutex.RUnlock()
|
|
||||||
return true, ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex.RUnlock()
|
mutex.RUnlock()
|
||||||
return false, ArErr{}
|
return false, ArErr{}
|
||||||
|
}
|
||||||
|
mutex.RUnlock()
|
||||||
|
return true, ArErr{}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"__NotContains__": builtinFunc{
|
"__NotContains__": builtinFunc{
|
||||||
@@ -210,29 +102,12 @@ func Map(m anymap) ArObject {
|
|||||||
return true, ArErr{}
|
return true, ArErr{}
|
||||||
}
|
}
|
||||||
mutex.RLock()
|
mutex.RLock()
|
||||||
if _, ok := m[key]; ok {
|
if _, ok := m[key]; !ok {
|
||||||
mutex.RUnlock()
|
|
||||||
return false, ArErr{}
|
|
||||||
}
|
|
||||||
for k := range m {
|
|
||||||
compare, err := runOperation(
|
|
||||||
operationType{
|
|
||||||
operation: 9,
|
|
||||||
values: []any{key, k},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if err.EXISTS {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if anyToBool(compare) {
|
|
||||||
mutex.RUnlock()
|
|
||||||
return false, ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex.RUnlock()
|
mutex.RUnlock()
|
||||||
return true, ArErr{}
|
return true, ArErr{}
|
||||||
|
}
|
||||||
|
mutex.RUnlock()
|
||||||
|
return false, ArErr{}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"__setindex__": builtinFunc{
|
"__setindex__": builtinFunc{
|
||||||
@@ -245,7 +120,6 @@ func Map(m anymap) ArObject {
|
|||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
if isUnhashable(args[0]) {
|
if isUnhashable(args[0]) {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "Runtime Error",
|
||||||
@@ -254,74 +128,12 @@ func Map(m anymap) ArObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
key := ArValidToAny(args[0])
|
key := ArValidToAny(args[0])
|
||||||
listenersMutex.RLock()
|
|
||||||
if _, ok := listeners[key]; ok {
|
|
||||||
for _, v := range listeners[key] {
|
|
||||||
runCall(
|
|
||||||
call{
|
|
||||||
Callable: v,
|
|
||||||
Args: []any{args[1]},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
listenersMutex.RUnlock()
|
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
m[key] = args[1]
|
m[key] = args[1]
|
||||||
mutex.Unlock()
|
mutex.Unlock()
|
||||||
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) {
|
||||||
@@ -341,198 +153,19 @@ func Map(m anymap) ArObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex.RLock()
|
mutex.RLock()
|
||||||
if v, ok := m[key]; ok {
|
if _, ok := m[key]; !ok {
|
||||||
mutex.RUnlock()
|
|
||||||
return v, ArErr{}
|
|
||||||
}
|
|
||||||
for k := range m {
|
|
||||||
compare, err := runOperation(
|
|
||||||
operationType{
|
|
||||||
operation: 9,
|
|
||||||
values: []any{key, k},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if err.EXISTS {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if anyToBool(compare) {
|
|
||||||
mutex.RUnlock()
|
|
||||||
return m[k], ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex.RUnlock()
|
mutex.RUnlock()
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "KeyError",
|
TYPE: "KeyError",
|
||||||
message: "key " + fmt.Sprint(key) + " not found",
|
message: "key " + fmt.Sprint(key) + " not found",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
obj.obj["__Equal__"] = builtinFunc{
|
v := m[key]
|
||||||
"__Equal__",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
debugPrintln("Equal", args)
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typeof(args[0]) != "map" {
|
|
||||||
return false, ArErr{}
|
|
||||||
}
|
|
||||||
a := ArValidToAny(args[0]).(anymap)
|
|
||||||
mutex.RLock()
|
|
||||||
if len(m) != len(a) {
|
|
||||||
mutex.RUnlock()
|
mutex.RUnlock()
|
||||||
return false, ArErr{}
|
return v, ArErr{}
|
||||||
}
|
|
||||||
for k, v := range m {
|
|
||||||
debugPrintln(k, v)
|
|
||||||
if _, ok := a[k]; !ok {
|
|
||||||
mutex.RUnlock()
|
|
||||||
return false, ArErr{}
|
|
||||||
}
|
|
||||||
val, err := runOperation(operationType{
|
|
||||||
operation: 9,
|
|
||||||
values: []any{v, a[k]},
|
|
||||||
}, stack{}, 0)
|
|
||||||
if err.EXISTS {
|
|
||||||
return val, err
|
|
||||||
}
|
|
||||||
if !anyToBool(val) {
|
|
||||||
mutex.RUnlock()
|
|
||||||
return false, ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex.RUnlock()
|
|
||||||
return true, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["copy"] = builtinFunc{
|
|
||||||
"copy",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
debugPrintln("copy", args)
|
|
||||||
if len(args) != 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 0 arguments, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex.RLock()
|
|
||||||
newMap := make(anymap)
|
|
||||||
for k, v := range m {
|
|
||||||
newMap[k] = v
|
|
||||||
}
|
|
||||||
mutex.RUnlock()
|
|
||||||
return newMap, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["addKeyChangeListener"] = builtinFunc{
|
|
||||||
"addKeyChangeListener",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 2 arguments, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key := ArValidToAny(args[0])
|
|
||||||
if isUnhashable(key) {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "unhashable type: " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typeof(args[1]) != "function" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected function, got " + typeof(args[1]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
id := currentID
|
|
||||||
currentID++
|
|
||||||
listenersMutex.Lock()
|
|
||||||
if _, ok := listeners[key]; !ok {
|
|
||||||
listeners[key] = map[uint32]any{}
|
|
||||||
}
|
|
||||||
listeners[key][id] = args[1]
|
|
||||||
listenersMutex.Unlock()
|
|
||||||
return anymap{
|
|
||||||
"remove": builtinFunc{
|
|
||||||
"remove",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 0 arguments, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
listenersMutex.Lock()
|
|
||||||
delete(listeners[key], id)
|
|
||||||
listenersMutex.Unlock()
|
|
||||||
return nil, ArErr{}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, ArErr{}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
obj.obj["keys"] = builtinFunc{
|
|
||||||
"keys",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 0 arguments, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex.RLock()
|
|
||||||
keys := []any{}
|
|
||||||
for k := range m {
|
|
||||||
keys = append(keys, AnyToArValid(k))
|
|
||||||
}
|
|
||||||
mutex.RUnlock()
|
|
||||||
return ArArray(keys), ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.obj["__Boolean__"] = builtinFunc{
|
|
||||||
"__Boolean__",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
mutex.RLock()
|
|
||||||
if len(m) == 0 {
|
|
||||||
mutex.RUnlock()
|
|
||||||
return false, ArErr{}
|
|
||||||
}
|
|
||||||
mutex.RUnlock()
|
|
||||||
return true, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
obj.obj["object"] = builtinFunc{
|
|
||||||
"object",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: "expected 0 arguments, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ArObject{
|
|
||||||
obj: m,
|
|
||||||
}, ArErr{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return obj
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "math/big"
|
var PI, _ = newNumber().SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
|
||||||
|
var e, _ = newNumber().SetString("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354")
|
||||||
var PI_RAT, _ = new(big.Rat).SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
|
var infinity, _ = newNumber().SetString("1e1000")
|
||||||
var PI ArObject
|
|
||||||
var e_RAT, _ = new(big.Rat).SetString("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354")
|
|
||||||
var e ArObject
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
PI = Number(PI_RAT)
|
|
||||||
e = Number(e_RAT)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ var negativeCompile = makeRegex(`( *)-(.|\n)+( *)`)
|
|||||||
|
|
||||||
type negative struct {
|
type negative struct {
|
||||||
VAL any
|
VAL any
|
||||||
sign bool
|
|
||||||
line int
|
line int
|
||||||
code string
|
code string
|
||||||
path string
|
path string
|
||||||
@@ -16,20 +15,15 @@ func isNegative(code UNPARSEcode) bool {
|
|||||||
return negativeCompile.MatchString(code.code)
|
return negativeCompile.MatchString(code.code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNegative(code UNPARSEcode, index int, codeline []UNPARSEcode) (any, bool, ArErr, int) {
|
func parseNegative(code UNPARSEcode, index int, codeline []UNPARSEcode) (negative, bool, ArErr, int) {
|
||||||
trimmed := strings.TrimSpace(code.code)
|
|
||||||
trimmednegative := strings.TrimLeft(trimmed, "-")
|
|
||||||
difference := len(trimmed) - len(trimmednegative)
|
|
||||||
resp, worked, err, i := translateVal(UNPARSEcode{
|
resp, worked, err, i := translateVal(UNPARSEcode{
|
||||||
code: trimmednegative,
|
code: strings.TrimSpace(code.code)[1:],
|
||||||
realcode: code.realcode,
|
realcode: code.realcode,
|
||||||
line: code.line,
|
line: code.line,
|
||||||
path: code.path,
|
path: code.path,
|
||||||
}, index, codeline, 0)
|
}, index, codeline, 0)
|
||||||
|
|
||||||
return negative{
|
return negative{
|
||||||
VAL: resp,
|
VAL: resp,
|
||||||
sign: difference%2 == 0,
|
|
||||||
line: code.line,
|
line: code.line,
|
||||||
code: code.realcode,
|
code: code.realcode,
|
||||||
path: code.path,
|
path: code.path,
|
||||||
|
|||||||
1765
src/number.go
1765
src/number.go
File diff suppressed because it is too large
Load Diff
@@ -2,29 +2,49 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var operations = []string{
|
var operations = [][]string{
|
||||||
|
{
|
||||||
"&&",
|
"&&",
|
||||||
|
" and ",
|
||||||
|
}, {
|
||||||
"||",
|
"||",
|
||||||
|
" or ",
|
||||||
|
}, {
|
||||||
" not in ",
|
" not in ",
|
||||||
|
}, {
|
||||||
" in ",
|
" in ",
|
||||||
|
}, {
|
||||||
"<=",
|
"<=",
|
||||||
|
}, {
|
||||||
">=",
|
">=",
|
||||||
|
}, {
|
||||||
"<",
|
"<",
|
||||||
|
}, {
|
||||||
">",
|
">",
|
||||||
|
}, {
|
||||||
"!=",
|
"!=",
|
||||||
|
}, {
|
||||||
"==",
|
"==",
|
||||||
|
}, {
|
||||||
"+",
|
"+",
|
||||||
|
}, {
|
||||||
"-",
|
"-",
|
||||||
|
}, {
|
||||||
"*",
|
"*",
|
||||||
|
}, {
|
||||||
"%",
|
"%",
|
||||||
|
}, {
|
||||||
"//",
|
"//",
|
||||||
|
}, {
|
||||||
"/",
|
"/",
|
||||||
|
}, {
|
||||||
"^",
|
"^",
|
||||||
}
|
"**",
|
||||||
|
}}
|
||||||
|
|
||||||
type operationType struct {
|
type operationType struct {
|
||||||
operation int
|
operation int
|
||||||
@@ -36,52 +56,49 @@ type operationType struct {
|
|||||||
|
|
||||||
func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (operationType, bool, ArErr, int) {
|
func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (operationType, bool, ArErr, int) {
|
||||||
for i := 0; i < len(operations); i++ {
|
for i := 0; i < len(operations); i++ {
|
||||||
split := strings.Split(code.code, operations[i])
|
values := []any{}
|
||||||
if len(split) < 2 {
|
current := 0
|
||||||
continue
|
totalindex := 1
|
||||||
}
|
for l := 0; l < len(code.code); l++ {
|
||||||
var values []any
|
for j := 0; j < len(operations[i]); j++ {
|
||||||
lookingAt := 0
|
if len(code.code[l:]) >= len(operations[i][j]) && code.code[l:l+len(operations[i][j])] == operations[i][j] {
|
||||||
totalStep := 1
|
|
||||||
for j := 1; j < len(split); j++ {
|
resp, success, _, respindex := translateVal(
|
||||||
if split[j-1] == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
joined := strings.Join(split[lookingAt:j], operations[i])
|
|
||||||
resp, success, err, respindex := translateVal(
|
|
||||||
UNPARSEcode{
|
UNPARSEcode{
|
||||||
code: joined,
|
code: code.code[current:l],
|
||||||
realcode: code.realcode,
|
realcode: code.realcode,
|
||||||
line: code.line,
|
line: code.line,
|
||||||
path: code.path,
|
path: code.path,
|
||||||
}, index, codelines, 0)
|
}, index, codelines, 0)
|
||||||
if !success || err.EXISTS {
|
|
||||||
continue
|
if success {
|
||||||
}
|
totalindex += respindex - 1
|
||||||
values = append(values, resp)
|
values = append(values, resp)
|
||||||
totalStep += respindex - 1
|
current = l + len(operations[i][j])
|
||||||
lookingAt = j
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(values) > 0 {
|
if len(values) > 0 {
|
||||||
resp, success, err, respindex := translateVal(
|
resp, success, err, respindex := translateVal(
|
||||||
UNPARSEcode{
|
UNPARSEcode{
|
||||||
code: strings.Join(split[lookingAt:], operations[i]),
|
code: code.code[current:],
|
||||||
realcode: code.realcode,
|
realcode: code.realcode,
|
||||||
line: code.line,
|
line: code.line,
|
||||||
path: code.path,
|
path: code.path,
|
||||||
}, index, codelines, 0)
|
}, index, codelines, 0)
|
||||||
if !success || err.EXISTS {
|
if success {
|
||||||
continue
|
totalindex += respindex - 1
|
||||||
}
|
|
||||||
values = append(values, resp)
|
values = append(values, resp)
|
||||||
totalStep += respindex - 1
|
|
||||||
return operationType{
|
return operationType{
|
||||||
operation: i,
|
i,
|
||||||
values: values,
|
values,
|
||||||
line: code.line,
|
code.line,
|
||||||
code: code.realcode,
|
code.realcode,
|
||||||
path: code.path,
|
code.path,
|
||||||
}, true, ArErr{}, totalStep
|
}, true, err, totalindex
|
||||||
|
}
|
||||||
|
return operationType{}, false, err, totalindex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return operationType{}, false, ArErr{}, 0
|
return operationType{}, false, ArErr{}, 0
|
||||||
@@ -112,12 +129,15 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
|||||||
stack,
|
stack,
|
||||||
stacklevel+1,
|
stacklevel+1,
|
||||||
)
|
)
|
||||||
|
resp2 = ArValidToAny(resp2)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
switch o.operation {
|
switch o.operation {
|
||||||
case 4:
|
case 4:
|
||||||
if x, ok := resp.(ArObject); ok {
|
if isAnyNumber(resp) && isAnyNumber(resp2) {
|
||||||
|
return resp.(number).Cmp(resp2.(number)) <= 0, ArErr{}
|
||||||
|
} else if x, ok := resp.(ArObject); ok {
|
||||||
if y, ok := x.obj["__LessThanEqual__"]; ok {
|
if y, ok := x.obj["__LessThanEqual__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -142,7 +162,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
|||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
case 5:
|
case 5:
|
||||||
if x, ok := resp.(ArObject); ok {
|
if isAnyNumber(resp) && isAnyNumber(resp2) {
|
||||||
|
return resp.(number).Cmp(resp2.(number)) >= 0, ArErr{}
|
||||||
|
} else if x, ok := resp.(ArObject); ok {
|
||||||
if y, ok := x.obj["__GreaterThanEqual__"]; ok {
|
if y, ok := x.obj["__GreaterThanEqual__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -167,7 +189,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
|||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
case 6:
|
case 6:
|
||||||
if x, ok := resp.(ArObject); ok {
|
if isAnyNumber(resp) && isAnyNumber(resp2) {
|
||||||
|
return resp.(number).Cmp(resp2.(number)) < 0, ArErr{}
|
||||||
|
} else if x, ok := resp.(ArObject); ok {
|
||||||
if y, ok := x.obj["__LessThan__"]; ok {
|
if y, ok := x.obj["__LessThan__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -192,7 +216,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
|||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
case 7:
|
case 7:
|
||||||
if x, ok := resp.(ArObject); ok {
|
if isAnyNumber(resp) && isAnyNumber(resp2) {
|
||||||
|
return resp.(number).Cmp(resp2.(number)) > 0, ArErr{}
|
||||||
|
} else if x, ok := resp.(ArObject); ok {
|
||||||
if y, ok := x.obj["__GreaterThan__"]; ok {
|
if y, ok := x.obj["__GreaterThan__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -217,9 +243,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
|||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
case 8:
|
case 8:
|
||||||
return notequals(resp, resp2, o, stack, stacklevel+1)
|
return notequals(resp, resp2, o, stack, stacklevel)
|
||||||
case 9:
|
case 9:
|
||||||
return equals(resp, resp2, o, stack, stacklevel+1)
|
return equals(resp, resp2, o, stack, stacklevel)
|
||||||
default:
|
default:
|
||||||
return false, ArErr{
|
return false, ArErr{
|
||||||
"Runtime Error",
|
"Runtime Error",
|
||||||
@@ -242,6 +268,9 @@ func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
output := resp
|
output := resp
|
||||||
|
if isAnyNumber(resp) {
|
||||||
|
output = newNumber().Set(resp.(number))
|
||||||
|
}
|
||||||
for i := 1; i < len(o.values); i++ {
|
for i := 1; i < len(o.values); i++ {
|
||||||
resp, err := runVal(
|
resp, err := runVal(
|
||||||
o.values[i],
|
o.values[i],
|
||||||
@@ -251,7 +280,10 @@ func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if x, ok := output.(ArObject); ok {
|
if typeof(output) == "number" && typeof(resp) == "number" {
|
||||||
|
output = output.(number).Sub(output.(number), resp.(number))
|
||||||
|
continue
|
||||||
|
} else if x, ok := output.(ArObject); ok {
|
||||||
if y, ok := x.obj["__Subtract__"]; ok {
|
if y, ok := x.obj["__Subtract__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -292,17 +324,23 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
output := resp
|
output := resp
|
||||||
|
if isAnyNumber(resp) {
|
||||||
|
output = newNumber().Set(resp.(number))
|
||||||
|
}
|
||||||
for i := 1; i < len(o.values); i++ {
|
for i := 1; i < len(o.values); i++ {
|
||||||
resp, err := runVal(
|
resp, err := runVal(
|
||||||
o.values[i],
|
o.values[i],
|
||||||
stack,
|
stack,
|
||||||
stacklevel+1,
|
stacklevel+1,
|
||||||
)
|
)
|
||||||
|
resp = ArValidToAny(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if x, ok := output.(ArObject); ok {
|
if typeof(resp) == "number" && typeof(output) == "number" {
|
||||||
|
output = output.(number).Quo(output.(number), resp.(number))
|
||||||
|
continue
|
||||||
|
} else if x, ok := output.(ArObject); ok {
|
||||||
if y, ok := x.obj["__Divide__"]; ok {
|
if y, ok := x.obj["__Divide__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -342,6 +380,9 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var output any = resp
|
var output any = resp
|
||||||
|
if typeof(output) == "number" {
|
||||||
|
output = newNumber().Set(output.(number))
|
||||||
|
}
|
||||||
for i := 1; i < len(o.values); i++ {
|
for i := 1; i < len(o.values); i++ {
|
||||||
resp, err := runVal(
|
resp, err := runVal(
|
||||||
o.values[i],
|
o.values[i],
|
||||||
@@ -351,7 +392,10 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if x, ok := output.(ArObject); ok {
|
if typeof(output) == "number" && typeof(resp) == "number" {
|
||||||
|
output = output.(number).Add(output.(number), resp.(number))
|
||||||
|
continue
|
||||||
|
} else if x, ok := output.(ArObject); ok {
|
||||||
if y, ok := x.obj["__Add__"]; ok {
|
if y, ok := x.obj["__Add__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -361,28 +405,13 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
o.line,
|
o.line,
|
||||||
o.path,
|
o.path,
|
||||||
}, stack, stacklevel+1)
|
}, stack, stacklevel+1)
|
||||||
if !err.EXISTS {
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
output = val
|
output = val
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if x, ok := resp.(ArObject); ok {
|
|
||||||
if y, ok := x.obj["__PostAdd__"]; ok {
|
|
||||||
val, err := runCall(
|
|
||||||
call{
|
|
||||||
y,
|
|
||||||
[]any{output},
|
|
||||||
o.code,
|
|
||||||
o.line,
|
|
||||||
o.path,
|
|
||||||
}, stack, stacklevel+1)
|
|
||||||
if !err.EXISTS {
|
|
||||||
output = val
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"Runtime Error",
|
"Runtime Error",
|
||||||
"Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
|
"Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
|
||||||
@@ -392,7 +421,7 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return output, ArErr{}
|
return (output), ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||||
@@ -406,6 +435,9 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var output any = resp
|
var output any = resp
|
||||||
|
if isAnyNumber(resp) {
|
||||||
|
output = newNumber().Set(resp.(number))
|
||||||
|
}
|
||||||
for i := 1; i < len(o.values); i++ {
|
for i := 1; i < len(o.values); i++ {
|
||||||
resp, err := runVal(
|
resp, err := runVal(
|
||||||
o.values[i],
|
o.values[i],
|
||||||
@@ -415,7 +447,10 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if x, ok := output.(ArObject); ok {
|
if typeof(output) == "number" && typeof(resp) == "number" {
|
||||||
|
output = output.(number).Mul(output.(number), resp.(number))
|
||||||
|
continue
|
||||||
|
} else if x, ok := output.(ArObject); ok {
|
||||||
if y, ok := x.obj["__Multiply__"]; ok {
|
if y, ok := x.obj["__Multiply__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -425,28 +460,13 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
o.line,
|
o.line,
|
||||||
o.path,
|
o.path,
|
||||||
}, stack, stacklevel+1)
|
}, stack, stacklevel+1)
|
||||||
if !err.EXISTS {
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
output = val
|
output = val
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if x, ok := resp.(ArObject); ok {
|
|
||||||
if y, ok := x.obj["__PostMultiply__"]; ok {
|
|
||||||
val, err := runCall(
|
|
||||||
call{
|
|
||||||
y,
|
|
||||||
[]any{output},
|
|
||||||
o.code,
|
|
||||||
o.line,
|
|
||||||
o.path,
|
|
||||||
}, stack, stacklevel+1)
|
|
||||||
if !err.EXISTS {
|
|
||||||
output = val
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"Runtime Error",
|
"Runtime Error",
|
||||||
"Cannot multiply type '" + typeof(resp) + "'",
|
"Cannot multiply type '" + typeof(resp) + "'",
|
||||||
@@ -468,7 +488,7 @@ func calcAnd(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
stack,
|
stack,
|
||||||
stacklevel+1,
|
stacklevel+1,
|
||||||
)
|
)
|
||||||
|
resp = ArValidToAny(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -488,7 +508,7 @@ func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
stack,
|
stack,
|
||||||
stacklevel+1,
|
stacklevel+1,
|
||||||
)
|
)
|
||||||
|
resp = ArValidToAny(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -524,7 +544,7 @@ func calcNotIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
stack,
|
stack,
|
||||||
stacklevel+1,
|
stacklevel+1,
|
||||||
)
|
)
|
||||||
|
resp = ArValidToAny(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -609,7 +629,9 @@ func calcIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||||
if x, ok := a.(ArObject); ok {
|
if typeof(a) == "number" && typeof(b) == "number" {
|
||||||
|
return a.(number).Cmp(b.(number)) != 0, ArErr{}
|
||||||
|
} else if x, ok := a.(ArObject); ok {
|
||||||
if y, ok := x.obj["__NotEqual__"]; ok {
|
if y, ok := x.obj["__NotEqual__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -619,33 +641,19 @@ func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool
|
|||||||
o.line,
|
o.line,
|
||||||
o.path,
|
o.path,
|
||||||
}, stack, stacklevel+1)
|
}, stack, stacklevel+1)
|
||||||
if !err.EXISTS {
|
|
||||||
return anyToBool(val), ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if x, ok := b.(ArObject); ok {
|
|
||||||
if y, ok := x.obj["__NotEqual__"]; ok {
|
|
||||||
val, err := runCall(
|
|
||||||
call{
|
|
||||||
y,
|
|
||||||
[]any{a},
|
|
||||||
o.code,
|
|
||||||
o.line,
|
|
||||||
o.path,
|
|
||||||
}, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return anyToBool(val), ArErr{}
|
return !anyToBool(val), ArErr{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return !reflect.DeepEqual(a, b), ArErr{}
|
return !reflect.DeepEqual(a, b), ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||||
debugPrintln("equals", a, b)
|
if typeof(a) == "number" && typeof(b) == "number" {
|
||||||
if x, ok := a.(ArObject); ok {
|
return a.(number).Cmp(b.(number)) == 0, ArErr{}
|
||||||
|
} else if x, ok := a.(ArObject); ok {
|
||||||
if y, ok := x.obj["__Equal__"]; ok {
|
if y, ok := x.obj["__Equal__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -655,21 +663,6 @@ func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, A
|
|||||||
o.line,
|
o.line,
|
||||||
o.path,
|
o.path,
|
||||||
}, stack, stacklevel+1)
|
}, stack, stacklevel+1)
|
||||||
if !err.EXISTS {
|
|
||||||
return anyToBool(val), ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if x, ok := b.(ArObject); ok {
|
|
||||||
if y, ok := x.obj["__Equal__"]; ok {
|
|
||||||
val, err := runCall(
|
|
||||||
call{
|
|
||||||
y,
|
|
||||||
[]any{a},
|
|
||||||
o.code,
|
|
||||||
o.line,
|
|
||||||
o.path,
|
|
||||||
}, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -685,20 +678,32 @@ func calcMod(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
stack,
|
stack,
|
||||||
stacklevel+1,
|
stacklevel+1,
|
||||||
)
|
)
|
||||||
|
resp = ArValidToAny(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
output := resp
|
output := resp
|
||||||
|
if isAnyNumber(resp) {
|
||||||
|
output = newNumber().Set(resp.(number))
|
||||||
|
}
|
||||||
for i := 1; i < len(o.values); i++ {
|
for i := 1; i < len(o.values); i++ {
|
||||||
resp, err := runVal(
|
resp, err := runVal(
|
||||||
o.values[i],
|
o.values[i],
|
||||||
stack,
|
stack,
|
||||||
stacklevel+1,
|
stacklevel+1,
|
||||||
)
|
)
|
||||||
|
resp = ArValidToAny(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if x, ok := output.(ArObject); ok {
|
if typeof(resp) == "number" && typeof(output) == "number" {
|
||||||
|
x := newNumber().Set(resp.(number))
|
||||||
|
x.Quo(output.(number), x)
|
||||||
|
x = floor(x)
|
||||||
|
x.Mul(x, resp.(number))
|
||||||
|
output.(number).Sub(output.(number), x)
|
||||||
|
continue
|
||||||
|
} else if x, ok := output.(ArObject); ok {
|
||||||
if y, ok := x.obj["__Modulo__"]; ok {
|
if y, ok := x.obj["__Modulo__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -737,17 +742,23 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
output := resp
|
output := resp
|
||||||
|
if isAnyNumber(resp) {
|
||||||
|
output = newNumber().Set(resp.(number))
|
||||||
|
}
|
||||||
for i := 1; i < len(o.values); i++ {
|
for i := 1; i < len(o.values); i++ {
|
||||||
resp, err := runVal(
|
resp, err := runVal(
|
||||||
o.values[i],
|
o.values[i],
|
||||||
stack,
|
stack,
|
||||||
stacklevel+1,
|
stacklevel+1,
|
||||||
)
|
)
|
||||||
|
resp = ArValidToAny(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if x, ok := output.(ArObject); ok {
|
if typeof(resp) == "number" && typeof(output) == "number" {
|
||||||
|
output = output.(number).Quo(output.(number), resp.(number))
|
||||||
|
continue
|
||||||
|
} else if x, ok := output.(ArObject); ok {
|
||||||
if y, ok := x.obj["__IntDivide__"]; ok {
|
if y, ok := x.obj["__IntDivide__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
@@ -766,7 +777,7 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"Runtime Error",
|
"Runtime Error",
|
||||||
"Cannot int divide type '" + typeof(resp) + "'",
|
"Cannot divide type '" + typeof(resp) + "'",
|
||||||
o.line,
|
o.line,
|
||||||
o.path,
|
o.path,
|
||||||
o.code,
|
o.code,
|
||||||
@@ -776,142 +787,56 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return output, ArErr{}
|
return output, ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||||
// resp, err := runVal(
|
|
||||||
// o.values[0],
|
|
||||||
// stack,
|
|
||||||
// stacklevel+1,
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// if err.EXISTS {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// if typeof(resp) != "number" {
|
|
||||||
// return nil, ArErr{
|
|
||||||
// "Runtime Error",
|
|
||||||
// "Cannot calculate power of type '" + typeof(resp) + "'",
|
|
||||||
// o.line,
|
|
||||||
// o.path,
|
|
||||||
// o.code,
|
|
||||||
// true,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// output := newNumber().Set(resp.(number))
|
|
||||||
// for i := 1; i < len(o.values); i++ {
|
|
||||||
// resp, err := runVal(
|
|
||||||
// o.values[i],
|
|
||||||
// stack,
|
|
||||||
// stacklevel+1,
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// if err.EXISTS {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// if typeof(resp) == "number" {
|
|
||||||
// n := newNumber().Set(resp.(number))
|
|
||||||
// if n.Cmp(newNumber().SetInt64(10)) <= 0 {
|
|
||||||
// toOut := newNumber().SetInt64(1)
|
|
||||||
// clone := newNumber().Set(output)
|
|
||||||
// nAbs := (abs(newNumber().Set(n)))
|
|
||||||
// j := newNumber()
|
|
||||||
// for ; j.Cmp(nAbs) < 0; j.Add(j, one) {
|
|
||||||
// toOut.Mul(toOut, clone)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// nAbs.Sub(nAbs, j)
|
|
||||||
// if nAbs.Cmp(newNumber()) < 0 {
|
|
||||||
// j.Sub(j, one)
|
|
||||||
// n1, _ := toOut.Float64()
|
|
||||||
// n2, _ := nAbs.Float64()
|
|
||||||
// calculated := newNumber().SetFloat64(math.Pow(n1, n2))
|
|
||||||
// if calculated == nil {
|
|
||||||
// calculated = infinity
|
|
||||||
// }
|
|
||||||
// toOut.Mul(toOut, calculated)
|
|
||||||
// }
|
|
||||||
// if n.Cmp(newNumber()) < 0 {
|
|
||||||
// toOut.Quo(newNumber().SetInt64(1), toOut)
|
|
||||||
// }
|
|
||||||
// output.Set(toOut)
|
|
||||||
// } else if n.Cmp(newNumber().SetInt64(1)) != 0 {
|
|
||||||
// n1, _ := output.Float64()
|
|
||||||
// n2, _ := n.Float64()
|
|
||||||
// calculated := newNumber().SetFloat64(math.Pow(n1, n2))
|
|
||||||
// if calculated == nil {
|
|
||||||
// calculated = infinity
|
|
||||||
// }
|
|
||||||
// output.Mul(output, calculated)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /*
|
|
||||||
// n1, _ := output.Float64()
|
|
||||||
// n2, _ := resp.(number).Float64()
|
|
||||||
// output = newNumber().SetFloat64(math.Pow(n1, n2))
|
|
||||||
// if output == nil {
|
|
||||||
// output = infinity
|
|
||||||
// }
|
|
||||||
// */
|
|
||||||
// } else {
|
|
||||||
// return nil, ArErr{
|
|
||||||
// "Runtime Error",
|
|
||||||
// "Cannot calculate power of type '" + typeof(resp) + "'",
|
|
||||||
// o.line,
|
|
||||||
// o.path,
|
|
||||||
// o.code,
|
|
||||||
// true,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return output, ArErr{}
|
|
||||||
// }
|
|
||||||
|
|
||||||
func calcPower(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
|
||||||
|
|
||||||
resp, err := runVal(
|
resp, err := runVal(
|
||||||
o.values[0],
|
o.values[0],
|
||||||
stack,
|
stack,
|
||||||
stacklevel+1,
|
stacklevel+1,
|
||||||
)
|
)
|
||||||
|
resp = ArValidToAny(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var output any = resp
|
if typeof(resp) != "number" {
|
||||||
for i := 1; i < len(o.values); i++ {
|
|
||||||
resp, err := runVal(
|
|
||||||
o.values[i],
|
|
||||||
stack,
|
|
||||||
stacklevel+1,
|
|
||||||
)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if x, ok := output.(ArObject); ok {
|
|
||||||
if y, ok := x.obj["__Power__"]; ok {
|
|
||||||
val, err := runCall(
|
|
||||||
call{
|
|
||||||
y,
|
|
||||||
[]any{resp},
|
|
||||||
o.code,
|
|
||||||
o.line,
|
|
||||||
o.path,
|
|
||||||
}, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
output = val
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"Runtime Error",
|
"Runtime Error",
|
||||||
"Cannot power type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
|
"Cannot calculate power of type '" + typeof(resp) + "'",
|
||||||
o.line,
|
o.line,
|
||||||
o.path,
|
o.path,
|
||||||
o.code,
|
o.code,
|
||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (output), ArErr{}
|
output := newNumber().Set(resp.(number))
|
||||||
|
for i := 1; i < len(o.values); i++ {
|
||||||
|
resp, err := runVal(
|
||||||
|
o.values[i],
|
||||||
|
stack,
|
||||||
|
stacklevel+1,
|
||||||
|
)
|
||||||
|
resp = ArValidToAny(resp)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if typeof(resp) == "number" {
|
||||||
|
n1, _ := output.Float64()
|
||||||
|
n2, _ := resp.(number).Float64()
|
||||||
|
output = newNumber().SetFloat64(math.Pow(n1, n2))
|
||||||
|
if output == nil {
|
||||||
|
output = infinity
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, ArErr{
|
||||||
|
"Runtime Error",
|
||||||
|
"Cannot calculate power of type '" + typeof(resp) + "'",
|
||||||
|
o.line,
|
||||||
|
o.path,
|
||||||
|
o.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output, ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"os"
|
||||||
"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
|
filePath any
|
||||||
translated translatedImport
|
values any
|
||||||
FilePath any
|
code string
|
||||||
Values any
|
line int
|
||||||
Code string
|
path string
|
||||||
Line int
|
|
||||||
Path string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isGenericImport(code UNPARSEcode) bool {
|
func isGenericImport(code UNPARSEcode) bool {
|
||||||
@@ -24,154 +22,66 @@ func isGenericImport(code UNPARSEcode) bool {
|
|||||||
func parseGenericImport(code UNPARSEcode, index int, codeline []UNPARSEcode) (ArImport, bool, ArErr, int) {
|
func parseGenericImport(code UNPARSEcode, index int, codeline []UNPARSEcode) (ArImport, bool, ArErr, int) {
|
||||||
trim := strings.Trim(code.code, " ")
|
trim := strings.Trim(code.code, " ")
|
||||||
pathAndAs := trim[6:]
|
pathAndAs := trim[6:]
|
||||||
split := strings.Split(pathAndAs, " as ")
|
split := strings.SplitN(pathAndAs, " as ", 2)
|
||||||
var toImport any
|
toImportstr := strings.TrimSpace(split[0])
|
||||||
var asStr any
|
asStr := strings.TrimSpace(split[1])
|
||||||
var i = 1
|
toImport, worked, err, i := translateVal(UNPARSEcode{
|
||||||
if len(split) == 1 {
|
code: toImportstr,
|
||||||
toImportval, worked, err, I := translateVal(UNPARSEcode{
|
|
||||||
code: strings.Trim(split[0], " "),
|
|
||||||
realcode: code.realcode,
|
realcode: code.realcode,
|
||||||
line: code.line,
|
line: code.line,
|
||||||
path: code.path,
|
path: code.path,
|
||||||
}, index, codeline, 0)
|
}, index, codeline, 0)
|
||||||
if !worked || err.EXISTS {
|
if !worked {
|
||||||
return ArImport{}, worked, err, I
|
return ArImport{}, false, err, i
|
||||||
}
|
}
|
||||||
toImport = toImportval
|
return ArImport{
|
||||||
i = I
|
|
||||||
} else {
|
|
||||||
for i := 1; i < len(split); i++ {
|
|
||||||
before := strings.Trim(strings.Join(split[:i], " as "), " ")
|
|
||||||
after := strings.Trim(strings.Join(split[i:], " as "), " ")
|
|
||||||
toImportval, worked, err, I := translateVal(UNPARSEcode{
|
|
||||||
code: before,
|
|
||||||
realcode: code.realcode,
|
|
||||||
line: code.line,
|
|
||||||
path: code.path,
|
|
||||||
}, index, codeline, 0)
|
|
||||||
i = I
|
|
||||||
if !worked || err.EXISTS {
|
|
||||||
if i == len(split)-1 {
|
|
||||||
return ArImport{}, worked, err, i
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if after == "" {
|
|
||||||
} else if after == "*" {
|
|
||||||
asStr = true
|
|
||||||
} else if variableCompile.MatchString(after) {
|
|
||||||
asStr = after
|
|
||||||
} else {
|
|
||||||
return ArImport{}, false, ArErr{"Syntax Error", "invalid variable name '" + after + "'", code.line, code.path, code.realcode, true}, i
|
|
||||||
}
|
|
||||||
toImport = toImportval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
return nil, ArErr{"Import Error", "importing in WASM is currently not supported", importOBJ.line, importOBJ.path, importOBJ.code, true}
|
||||||
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 {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
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}
|
||||||
}
|
}
|
||||||
parent := filepath.Dir(filepath.ToSlash(importOBJ.Path))
|
path := val.(string)
|
||||||
translated, err = translateImport(val.(string), parent, false)
|
ex, e := os.Getwd()
|
||||||
|
if e != nil {
|
||||||
|
return nil, ArErr{"File Error", "could not get current working directory", importOBJ.line, importOBJ.path, importOBJ.code, true}
|
||||||
|
}
|
||||||
|
stackMap, err := importMod(path, ex, false, stack[0])
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
if err.line == 0 {
|
if err.line == 0 {
|
||||||
err.line = importOBJ.Line
|
err.line = importOBJ.line
|
||||||
}
|
}
|
||||||
if err.path == "" {
|
if err.path == "" {
|
||||||
err.path = importOBJ.Path
|
err.path = importOBJ.path
|
||||||
}
|
}
|
||||||
if err.code == "" {
|
if err.code == "" {
|
||||||
err.code = importOBJ.Code
|
err.code = importOBJ.code
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
switch x := importOBJ.values.(type) {
|
||||||
stackMap, err := runTranslatedImport(translated, stack[0], 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
|
|
||||||
}
|
|
||||||
setindex, ok := stack[len(stack)-1].obj["__setindex__"]
|
|
||||||
if !ok {
|
|
||||||
return nil, ArErr{
|
|
||||||
"Import Error",
|
|
||||||
"could not find __setindex__ in module scope",
|
|
||||||
importOBJ.Line,
|
|
||||||
importOBJ.Path,
|
|
||||||
importOBJ.Code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch x := importOBJ.Values.(type) {
|
|
||||||
case []string:
|
case []string:
|
||||||
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(translated.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(path, true, false, 3, 0, false, 0), importOBJ.line, importOBJ.path, importOBJ.code, true}
|
||||||
}
|
}
|
||||||
builtinCall(setindex, []any{v, val})
|
stack[len(stack)-1].obj[v] = val
|
||||||
}
|
}
|
||||||
case string:
|
case string:
|
||||||
builtinCall(setindex, []any{x, stackMap})
|
stack[len(stack)-1].obj[x] = stackMap
|
||||||
case bool:
|
|
||||||
keyGetter, ok := stackMap.obj["keys"]
|
|
||||||
if !ok {
|
|
||||||
return nil, ArErr{"Import Error", "could not find keys in module scope", importOBJ.Line, importOBJ.Path, importOBJ.Code, true}
|
|
||||||
}
|
|
||||||
valueGetter, ok := stackMap.obj["__getindex__"]
|
|
||||||
if !ok {
|
|
||||||
return nil, ArErr{"Import Error", "could not find __getindex__ in module scope", importOBJ.Line, importOBJ.Path, importOBJ.Code, true}
|
|
||||||
}
|
|
||||||
keys, err := builtinCall(keyGetter, []any{})
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keys = ArValidToAny(keys)
|
|
||||||
for _, v := range keys.([]any) {
|
|
||||||
val, err := builtinCall(valueGetter, []any{v})
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
builtinCall(setindex, []any{v, val})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}
|
}
|
||||||
|
|||||||
244
src/path.go
244
src/path.go
@@ -1,244 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ArPath = Map(
|
|
||||||
anymap{
|
|
||||||
"ReadDir": builtinFunc{
|
|
||||||
"ReadDir",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "ReadDir takes exactly 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
if typeof(args[0]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "ReadDir argument must be a string, got " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
files, err := os.ReadDir(args[0].(string))
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var ret []any
|
|
||||||
for _, file := range files {
|
|
||||||
ret = append(ret, file.Name())
|
|
||||||
}
|
|
||||||
return ret, ArErr{}
|
|
||||||
}},
|
|
||||||
"exists": builtinFunc{
|
|
||||||
"exists",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "exists takes exactly 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
if typeof(args[0]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "exists argument must be a string, got " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err := os.Stat(args[0].(string))
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return false, ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true, ArErr{}
|
|
||||||
}},
|
|
||||||
"mkAllDir": builtinFunc{
|
|
||||||
"mkAllDir",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "mkAllDir takes exactly 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
if typeof(args[0]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "mkAllDir argument must be a string, got " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := os.MkdirAll(args[0].(string), os.ModePerm)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
|
||||||
}},
|
|
||||||
"mkDir": builtinFunc{
|
|
||||||
"mkDir",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "mkDir takes exactly 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
if typeof(args[0]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "mkDir argument must be a string, got " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := os.Mkdir(args[0].(string), os.ModePerm)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
|
||||||
}},
|
|
||||||
"remove": builtinFunc{
|
|
||||||
"remove",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "remove takes exactly 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
if typeof(args[0]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "remove argument must be a string, got " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := os.Remove(args[0].(string))
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
|
||||||
}},
|
|
||||||
"isDir": builtinFunc{
|
|
||||||
"isDir",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "isDir takes exactly 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
if typeof(args[0]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "isDir argument must be a string, got " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stat, err := os.Stat(args[0].(string))
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return false, ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return stat.IsDir(), ArErr{}
|
|
||||||
}},
|
|
||||||
"join": builtinFunc{
|
|
||||||
"join",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "join takes exactly 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
switch arr := args[0].(type) {
|
|
||||||
case []any:
|
|
||||||
var Path []string
|
|
||||||
for _, x := range arr {
|
|
||||||
x = ArValidToAny(x)
|
|
||||||
if typeof(x) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "join argument must be an array of strings, got " + typeof(x),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Path = append(Path, x.(string))
|
|
||||||
}
|
|
||||||
return filepath.Join(Path...), ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "join argument must be an array, got " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
"parent": builtinFunc{
|
|
||||||
"parent",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "parent takes exactly 1 argument, got " + fmt.Sprint(len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
if typeof(args[0]) != "string" {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "parent argument must be a string, got " + typeof(args[0]),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return path.Dir(filepath.ToSlash(args[0].(string))), ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
108
src/random.go
108
src/random.go
@@ -6,10 +6,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var rand_source = rand.New(rand.NewSource(time.Now().UnixMicro()))
|
func random() number {
|
||||||
|
return newNumber().SetFloat64(
|
||||||
func random() ArObject {
|
rand.Float64(),
|
||||||
return Number(rand_source.Float64())
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func randomRange(args ...any) (any, ArErr) {
|
func randomRange(args ...any) (any, ArErr) {
|
||||||
@@ -33,88 +33,23 @@ func randomRange(args ...any) (any, ArErr) {
|
|||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
min := args[0].(ArObject)
|
min := args[0].(number)
|
||||||
max := args[1].(ArObject)
|
max := args[1].(number)
|
||||||
|
if min.Cmp(max) > 0 {
|
||||||
compare_num, err := CompareObjects(min, max)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
compare, Err := numberToInt64(compare_num)
|
|
||||||
if Err != nil {
|
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "Runtime Error",
|
||||||
message: Err.Error(),
|
message: "takes a min less than max",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
difference := newNumber().Sub(max, min)
|
||||||
if compare == 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "range() num 1 must be less than or equal to num 2",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
num_range, err := runOperation(
|
|
||||||
operationType{
|
|
||||||
operation: 11,
|
|
||||||
values: []any{max, min},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := num_range.(ArObject); !ok {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "could not subtract the two numbers to calculate the range",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
num_range_obj := num_range.(ArObject)
|
|
||||||
|
|
||||||
rand := random()
|
rand := random()
|
||||||
|
rand.Mul(rand, difference)
|
||||||
multiplier, err := runOperation(
|
rand.Add(rand, min)
|
||||||
operationType{
|
return rand, ArErr{}
|
||||||
operation: 12,
|
|
||||||
values: []any{rand, num_range_obj},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := multiplier.(ArObject); !ok {
|
var ArRandom = Map(anymap{
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "could not multiply the random number by the range",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return runOperation(
|
|
||||||
operationType{
|
|
||||||
operation: 10,
|
|
||||||
values: []any{multiplier, min},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
var ArRandom = ArObject{anymap{
|
|
||||||
"__call__": builtinFunc{"random", func(args ...any) (any, ArErr) {
|
"__call__": builtinFunc{"random", func(args ...any) (any, ArErr) {
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
@@ -148,15 +83,22 @@ var ArRandom = ArObject{anymap{
|
|||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_seed, err := numberToInt64(a[0].(ArObject))
|
if !a[0].(number).IsInt() {
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "Runtime Error",
|
||||||
message: err.Error(),
|
message: "takes an integer not a float",
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rand_source.Seed(new_seed)
|
rand.Seed(
|
||||||
|
a[0].(number).Num().Int64(),
|
||||||
|
)
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}},
|
}},
|
||||||
}}
|
})
|
||||||
|
|
||||||
|
func initRandom() {
|
||||||
|
rand.Seed(
|
||||||
|
time.Now().UnixMicro(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "github.com/wadey/go-rounding"
|
||||||
"github.com/wadey/go-rounding"
|
|
||||||
)
|
|
||||||
|
|
||||||
func floor(x number) number {
|
func floor(x number) number {
|
||||||
|
|
||||||
|
|||||||
89
src/run.go
89
src/run.go
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,9 +18,9 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return ArString(x), ArErr{}
|
return ArString(x), ArErr{}
|
||||||
case call:
|
case call:
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
linenum = x.Line
|
linenum = x.line
|
||||||
path = x.Path
|
path = x.path
|
||||||
code = x.Code
|
code = x.code
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return runCall(x, stack, stacklevel+1)
|
return runCall(x, stack, stacklevel+1)
|
||||||
@@ -35,17 +34,17 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return runFactorial(x, stack, stacklevel+1)
|
return runFactorial(x, stack, stacklevel+1)
|
||||||
case accessVariable:
|
case accessVariable:
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
linenum = x.Line
|
linenum = x.line
|
||||||
path = x.Path
|
path = x.path
|
||||||
code = x.Code
|
code = x.code
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return readVariable(x, stack)
|
return readVariable(x, stack)
|
||||||
case ArMapGet:
|
case ArMapGet:
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
linenum = x.Line
|
linenum = x.line
|
||||||
path = x.Path
|
path = x.path
|
||||||
code = x.Code
|
code = x.code
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return mapGet(x, stack, stacklevel+1)
|
return mapGet(x, stack, stacklevel+1)
|
||||||
@@ -57,30 +56,35 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
return setVariableValue(x, stack, stacklevel+1)
|
return setVariableValue(x, stack, stacklevel+1)
|
||||||
// case negative:
|
case negative:
|
||||||
// if stackoverflow {
|
if stackoverflow {
|
||||||
// linenum = x.line
|
linenum = x.line
|
||||||
// path = x.path
|
path = x.path
|
||||||
// code = x.code
|
code = x.code
|
||||||
// break
|
break
|
||||||
// }
|
}
|
||||||
// resp, err := runVal(x.VAL, stack, stacklevel+1)
|
resp, err := runVal(x.VAL, stack, stacklevel+1)
|
||||||
// resp = AnyToArValid(resp)
|
resp = AnyToArValid(resp)
|
||||||
// if err.EXISTS {
|
if err.EXISTS {
|
||||||
// return nil, err
|
return nil, err
|
||||||
// }
|
}
|
||||||
// switch y := resp.(type) {
|
switch y := resp.(type) {
|
||||||
// case compiledNumber:
|
case number:
|
||||||
// if !x.sign {
|
return newNumber().Neg(y), ArErr{}
|
||||||
// return Number(compiledNumber{new(big.Rat).Neg(y)}), ArErr{}
|
}
|
||||||
// }
|
return nil, ArErr{
|
||||||
// return y, ArErr{}
|
TYPE: "TypeError",
|
||||||
// }
|
message: "cannot negate a non-number",
|
||||||
// return nil, ArErr{
|
EXISTS: true,
|
||||||
// TYPE: "Type Error",
|
}
|
||||||
// message: "cannot negate a non-number",
|
case brackets:
|
||||||
// EXISTS: true,
|
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
|
||||||
@@ -177,21 +181,13 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
return runSquareroot(x, stack, stacklevel+1)
|
return runSquareroot(x, stack, stacklevel+1)
|
||||||
case createMap:
|
case ArImport:
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
linenum = x.line
|
linenum = x.line
|
||||||
path = x.path
|
path = x.path
|
||||||
code = x.code
|
code = x.code
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return runCreateMap(x, stack, stacklevel+1)
|
|
||||||
case ArImport:
|
|
||||||
if stackoverflow {
|
|
||||||
linenum = x.Line
|
|
||||||
path = x.Path
|
|
||||||
code = x.Code
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return runImport(x, stack, stacklevel+1)
|
return runImport(x, stack, stacklevel+1)
|
||||||
case ABS:
|
case ABS:
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
@@ -209,11 +205,7 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
return runTryCatch(x, stack, stacklevel+1)
|
return runTryCatch(x, stack, stacklevel+1)
|
||||||
case compiledNumber:
|
case bool, ArObject, number, nil:
|
||||||
return Number(x.value), ArErr{}
|
|
||||||
case int64, int, float64, float32, *big.Rat, *big.Int:
|
|
||||||
return Number(x), ArErr{}
|
|
||||||
case bool, ArObject, nil, Callable, builtinFunc, anymap:
|
|
||||||
return x, ArErr{}
|
return x, ArErr{}
|
||||||
}
|
}
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
@@ -227,7 +219,6 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("unreachable", reflect.TypeOf(line))
|
fmt.Println("unreachable", reflect.TypeOf(line))
|
||||||
fmt.Println(line)
|
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ArSequence(a ...any) (any, ArErr) {
|
func ArSequence(a ...any) (any, ArErr) {
|
||||||
if len(a) < 1 || len(a) > 2 {
|
if len(a) < 1 || len(a) > 2 {
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha256"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func sha256Hash(s string) string {
|
|
||||||
h := sha256.New()
|
|
||||||
h.Write([]byte(s))
|
|
||||||
bs := h.Sum(nil)
|
|
||||||
return fmt.Sprintf("%x", bs)
|
|
||||||
}
|
|
||||||
31
src/shell.go
31
src/shell.go
@@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func shell(global ArObject) {
|
func shell(global ArObject) {
|
||||||
@@ -19,30 +18,23 @@ func shell(global ArObject) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
fmt.Print("\x1b[32;5;25mWelcome to the Argon v3!\x1b[25m\n\n")
|
|
||||||
for {
|
for {
|
||||||
indent := 0
|
indo := false
|
||||||
previous := 0
|
|
||||||
totranslate := []UNPARSEcode{}
|
totranslate := []UNPARSEcode{}
|
||||||
textBefore := ">>>"
|
code := input("\x1b[38;5;240m>>> \x1b[0m\x1b[1;5;240m")
|
||||||
for i := 1; indent > 0 || (previous != indent && indent >= 0) || i == 1; i++ {
|
fmt.Print("\x1b[0m")
|
||||||
indentStr := strings.Repeat(" ", indent)
|
if code == "" {
|
||||||
line, err := input("\x1b[38;5;240m" + textBefore + indentStr + " \x1b[0m\x1b[1;5;25m")
|
continue
|
||||||
if err != nil {
|
|
||||||
fmt.Println("\x1b[0m\n\x1b[32;5;25mBye :)\x1b[0m")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
}
|
||||||
code := indentStr + line
|
indo = true
|
||||||
|
totranslate = append(totranslate, UNPARSEcode{code, code, 1, "<shell>"})
|
||||||
|
for i := 2; indo; i++ {
|
||||||
|
code := input("\x1b[38;5;240m... \x1b[0m\x1b[1;5;240m")
|
||||||
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)
|
if code == "" {
|
||||||
previous = indent
|
indo = false
|
||||||
if len(trimmed) >= 2 && trimmed[len(trimmed)-2:] == "do" {
|
|
||||||
indent++
|
|
||||||
} else if trimmed == "" {
|
|
||||||
indent--
|
|
||||||
}
|
}
|
||||||
textBefore = "..."
|
|
||||||
}
|
}
|
||||||
translated, translationerr := translate(totranslate)
|
translated, translationerr := translate(totranslate)
|
||||||
count := len(translated)
|
count := len(translated)
|
||||||
@@ -55,6 +47,7 @@ func shell(global ArObject) {
|
|||||||
if runimeErr.EXISTS {
|
if runimeErr.EXISTS {
|
||||||
panicErr(runimeErr)
|
panicErr(runimeErr)
|
||||||
} else if count == 1 {
|
} else if count == 1 {
|
||||||
|
|
||||||
fmt.Println(anyToArgon(output, true, true, 3, 0, true, 1))
|
fmt.Println(anyToArgon(output, true, true, 3, 0, true, 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
529
src/socket.go
529
src/socket.go
@@ -1,529 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ArSocketClient(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket takes exactly 2 arguments",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
} else if typeof(args[0]) != "string" {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket type must be a string",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
} else if typeof(args[1]) != "string" {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket address must be a string",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
networktype := ArValidToAny(args[0]).(string)
|
|
||||||
address := ArValidToAny(args[1]).(string)
|
|
||||||
conn, err := net.Dial(networktype, address)
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: fmt.Sprintf("Socket connection failed: %s", err.Error()),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ArObject{
|
|
||||||
obj: anymap{
|
|
||||||
"read": builtinFunc{
|
|
||||||
"read",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket.readData() takes exactly 1 argument",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf := make([]byte, args[0].(number).Num().Int64())
|
|
||||||
n, err := conn.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: fmt.Sprintf("Socket read failed: %s", err.Error()),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ArBuffer(buf[:n]), ArErr{}
|
|
||||||
}},
|
|
||||||
"readUntil": builtinFunc{
|
|
||||||
"readUntil",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket.readUntil() takes exactly 1 argument",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value := ArValidToAny(args[0])
|
|
||||||
if typeof(value) != "buffer" {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: fmt.Sprintf("Socket.readUntil() argument must be a buffer, not %s", typeof(value)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endBuf := value.([]byte)
|
|
||||||
reader := io.Reader(conn)
|
|
||||||
buf := make([]byte, len(endBuf))
|
|
||||||
var data []byte
|
|
||||||
for {
|
|
||||||
_, err := reader.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: fmt.Sprintf("Socket read failed: %s", err.Error()),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data = append(data, buf[0])
|
|
||||||
if len(data) >= len(endBuf) {
|
|
||||||
dataSlice := data[len(data)-len(endBuf):]
|
|
||||||
for i := 0; i < len(endBuf); i++ {
|
|
||||||
if dataSlice[i] != endBuf[i] {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if i == len(endBuf)-1 {
|
|
||||||
return ArBuffer(data), ArErr{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}},
|
|
||||||
"write": builtinFunc{
|
|
||||||
"write",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: fmt.Sprintf("write() takes exactly 1 argument (%d given)", len(args)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typeof(args[0]) != "buffer" {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: fmt.Sprintf("write() argument must be a buffer, not %s", typeof(args[0])),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args[0] = ArValidToAny(args[0])
|
|
||||||
if typeof(args[0]) != "buffer" {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: fmt.Sprintf("write() argument must be a buffer, not %s", typeof(args[0])),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err := conn.Write(args[0].([]byte))
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ArErr{}
|
|
||||||
}},
|
|
||||||
"close": builtinFunc{
|
|
||||||
"close",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is already closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := conn.Close()
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn = nil
|
|
||||||
return nil, ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"isClosed": builtinFunc{
|
|
||||||
"isClosed",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if conn == nil {
|
|
||||||
return true, ArErr{}
|
|
||||||
}
|
|
||||||
conn.SetWriteDeadline(time.Now().Add(1 * time.Millisecond))
|
|
||||||
_, err := conn.Write([]byte{})
|
|
||||||
conn.SetWriteDeadline(time.Time{})
|
|
||||||
if err != nil {
|
|
||||||
conn.Close()
|
|
||||||
conn = nil
|
|
||||||
return true, ArErr{}
|
|
||||||
}
|
|
||||||
return false, ArErr{}
|
|
||||||
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}, ArErr{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ArSocketServer(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket takes exactly 2 arguments",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
} else if typeof(args[0]) != "string" {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket type must be a string",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
} else if typeof(args[1]) != "number" {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket port must be a number",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
networktype := ArValidToAny(args[0]).(string)
|
|
||||||
port_num := args[1].(ArObject)
|
|
||||||
port, err := numberToInt64(port_num)
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ln, err := net.Listen(networktype, ":"+fmt.Sprint(port))
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Map(anymap{
|
|
||||||
"accept": builtinFunc{
|
|
||||||
"accept",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if ln == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn, err := ln.Accept()
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Map(anymap{
|
|
||||||
"read": builtinFunc{
|
|
||||||
"read",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket.readData() takes exactly 1 argument",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf := make([]byte, args[0].(number).Num().Int64())
|
|
||||||
n, err := conn.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ArBuffer(buf[:n]), ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"readUntil": builtinFunc{
|
|
||||||
"readUntil",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket.readUntil() takes exactly 1 argument",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value := ArValidToAny(args[0])
|
|
||||||
if typeof(value) != "buffer" {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Type Error",
|
|
||||||
message: fmt.Sprintf("Socket.readUntil() argument must be a buffer, not %s", typeof(value)),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endBuf := value.([]byte)
|
|
||||||
var data []byte
|
|
||||||
buf := make([]byte, 1)
|
|
||||||
lookingAt := 0
|
|
||||||
for {
|
|
||||||
n, err := io.ReadFull(conn, buf)
|
|
||||||
if err != nil {
|
|
||||||
return ArBuffer(data), ArErr{}
|
|
||||||
}
|
|
||||||
chunk := buf[:n]
|
|
||||||
data = append(data, chunk...)
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
if chunk[i] == endBuf[lookingAt] {
|
|
||||||
lookingAt++
|
|
||||||
if lookingAt == len(endBuf) {
|
|
||||||
data = append(data, chunk...)
|
|
||||||
return ArBuffer(data), ArErr{}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lookingAt = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
"clearTimeout": builtinFunc{
|
|
||||||
"clearTimeout",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 0 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket.clearTimeout() takes exactly 0 arguments",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn.SetDeadline(time.Time{})
|
|
||||||
return ArObject{}, ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"setTimeout": builtinFunc{
|
|
||||||
"setTimeout",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket.setTimeout() takes exactly 1 argument",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typeof(args[0]) != "number" {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket timeout must be a number",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timeout := args[0].(number)
|
|
||||||
if timeout.Denom().Int64() != 1 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket timeout must be an integer",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := conn.SetDeadline(time.Now().Add(time.Duration(timeout.Num().Int64()) * time.Millisecond))
|
|
||||||
if err != nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: err.Error(),
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ArObject{}, ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"write": builtinFunc{
|
|
||||||
"write",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket.writeData() takes exactly 1 argument",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data := ArValidToAny(args[0])
|
|
||||||
switch x := data.(type) {
|
|
||||||
case []any:
|
|
||||||
bytes := []byte{}
|
|
||||||
for _, v := range x {
|
|
||||||
if typeof(v) != "number" && v.(number).Denom().Int64() != 1 {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket.writeData() argument must be a array of integers",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bytes = append(bytes, byte(v.(number).Num().Int64()))
|
|
||||||
}
|
|
||||||
conn.Write(bytes)
|
|
||||||
return nil, ArErr{}
|
|
||||||
case []byte:
|
|
||||||
conn.Write(x)
|
|
||||||
return nil, ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket.writeData() argument must be a array of numbers",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"close": builtinFunc{
|
|
||||||
"close",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is already closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn.Close()
|
|
||||||
conn = nil
|
|
||||||
return nil, ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"isClosed": builtinFunc{
|
|
||||||
"isClosed",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if conn == nil {
|
|
||||||
return true, ArErr{}
|
|
||||||
}
|
|
||||||
conn.SetWriteDeadline(time.Now().Add(1 * time.Millisecond))
|
|
||||||
_, err := conn.Write([]byte{})
|
|
||||||
conn.SetWriteDeadline(time.Time{})
|
|
||||||
if err != nil {
|
|
||||||
conn.Close()
|
|
||||||
conn = nil
|
|
||||||
return true, ArErr{}
|
|
||||||
}
|
|
||||||
return false, ArErr{}
|
|
||||||
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"RemoteAddr": builtinFunc{
|
|
||||||
"RemoteAddr",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if conn == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Connection is closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ArString(conn.RemoteAddr().String()), ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"LocalAddr": builtinFunc{
|
|
||||||
"LocalAddr",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
return ArString(conn.LocalAddr().String()), ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}), ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"close": builtinFunc{
|
|
||||||
"close",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
if ln == nil {
|
|
||||||
return ArObject{}, ArErr{
|
|
||||||
TYPE: "Socket Error",
|
|
||||||
message: "Socket is already closed",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ln.Close()
|
|
||||||
ln = nil
|
|
||||||
return nil, ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"isClosed": builtinFunc{
|
|
||||||
"isClosed",
|
|
||||||
func(args ...any) (any, ArErr) {
|
|
||||||
return ln == nil, ArErr{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}), ArErr{}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"fmt"
|
|
||||||
)
|
type keyCache map[any]any
|
||||||
|
|
||||||
func quickSort(list []any, getKey func(any) (any, ArErr)) ([]any, ArErr) {
|
func quickSort(list []any, getKey func(any) (any, ArErr)) ([]any, ArErr) {
|
||||||
if len(list) <= 1 {
|
if len(list) <= 1 {
|
||||||
@@ -13,19 +13,21 @@ func quickSort(list []any, getKey func(any) (any, ArErr)) ([]any, ArErr) {
|
|||||||
var left []any
|
var left []any
|
||||||
var right []any
|
var right []any
|
||||||
|
|
||||||
|
var cache = make(keyCache)
|
||||||
|
|
||||||
for _, v := range list[1:] {
|
for _, v := range list[1:] {
|
||||||
val, err := getkeyCache(getKey, v)
|
val, err := getkeyCache(getKey, v, cache)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pivotval, err := getkeyCache(getKey, pivot)
|
pivotval, err := getkeyCache(getKey, pivot, cache)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
comp, comperr := compare(val, pivotval)
|
comp, comperr := compare(val, pivotval)
|
||||||
if comperr != nil {
|
if comperr != nil {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "TypeError",
|
||||||
message: comperr.Error(),
|
message: comperr.Error(),
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
@@ -49,21 +51,28 @@ func quickSort(list []any, getKey func(any) (any, ArErr)) ([]any, ArErr) {
|
|||||||
return append(append(left, pivot), right...), ArErr{}
|
return append(append(left, pivot), right...), ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getkeyCache(getKey func(any) (any, ArErr), key any) (any, ArErr) {
|
func getkeyCache(getKey func(any) (any, ArErr), index any, cache keyCache) (any, ArErr) {
|
||||||
val, err := getKey(key)
|
key := ArValidToAny(index)
|
||||||
|
if cacheval, ok := cache[key]; ok {
|
||||||
|
return cacheval, ArErr{}
|
||||||
|
}
|
||||||
|
val, err := getKey(index)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
cache[key] = val
|
||||||
return val, ArErr{}
|
return val, ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func compare(a, b any) (bool, error) {
|
func compare(a, b any) (bool, error) {
|
||||||
if x, ok := a.(ArObject); ok {
|
if isAnyNumber(a) && isAnyNumber(b) {
|
||||||
|
return a.(number).Cmp(b.(number)) < 0, nil
|
||||||
|
} else if x, ok := a.(ArObject); ok {
|
||||||
if y, ok := x.obj["__LessThan__"]; ok {
|
if y, ok := x.obj["__LessThan__"]; ok {
|
||||||
resp, err := runCall(
|
resp, err := runCall(
|
||||||
call{
|
call{
|
||||||
Callable: y,
|
callable: y,
|
||||||
Args: []any{b},
|
args: []any{b},
|
||||||
}, stack{}, 0)
|
}, stack{}, 0)
|
||||||
if !err.EXISTS {
|
if !err.EXISTS {
|
||||||
return anyToBool(resp), nil
|
return anyToBool(resp), nil
|
||||||
|
|||||||
141
src/string.go
141
src/string.go
@@ -5,7 +5,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
|
||||||
"golang.org/x/text/cases"
|
"golang.org/x/text/cases"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
)
|
)
|
||||||
@@ -16,36 +15,21 @@ func isString(code UNPARSEcode) bool {
|
|||||||
return stringCompile.MatchString(code.code)
|
return stringCompile.MatchString(code.code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func swapQuotes(text string) string {
|
|
||||||
result := ""
|
|
||||||
for _, char := range text {
|
|
||||||
switch char {
|
|
||||||
case '"':
|
|
||||||
result += "'"
|
|
||||||
case '\'':
|
|
||||||
result += "\""
|
|
||||||
default:
|
|
||||||
result += string(char)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func unquoted(
|
func unquoted(
|
||||||
str string,
|
str string,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
str = strings.Trim(str, " ")
|
str = strings.Trim(str, " ")
|
||||||
char := str[0]
|
if str[0] == '\'' {
|
||||||
if char == '\'' {
|
str = strings.Replace(str, "\\\"", "\"", -1)
|
||||||
str = swapQuotes(str)
|
str = strings.Replace(str, "\"", "\\\"", -1)
|
||||||
}
|
}
|
||||||
|
str = str[1 : len(str)-1]
|
||||||
|
str = strings.Replace(str, "\\'", "'", -1)
|
||||||
|
str = "\"" + str + "\""
|
||||||
output, err := strconv.Unquote(str)
|
output, err := strconv.Unquote(str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if char == '\'' {
|
|
||||||
output = swapQuotes(output)
|
|
||||||
}
|
|
||||||
return output, nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +39,7 @@ func parseString(code UNPARSEcode) (string, bool, ArErr, int) {
|
|||||||
|
|
||||||
unquoted, err := unquoted(trim)
|
unquoted, err := unquoted(trim)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", false, ArErr{"Syntax Error", "invalid escape sequence", code.line, code.path, code.realcode, true}, 1
|
return "", false, ArErr{"Syntax Error", "invalid string", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return unquoted, true, ArErr{}, 1
|
return unquoted, true, ArErr{}, 1
|
||||||
@@ -66,32 +50,7 @@ func ArString(str string) ArObject {
|
|||||||
anymap{
|
anymap{
|
||||||
"__value__": str,
|
"__value__": str,
|
||||||
"__name__": "string",
|
"__name__": "string",
|
||||||
},
|
"length": newNumber().SetUint64(uint64(len(str))),
|
||||||
}
|
|
||||||
|
|
||||||
obj.obj["__string__"] = builtinFunc{
|
|
||||||
"__string__",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
return str, ArErr{}
|
|
||||||
}}
|
|
||||||
obj.obj["__repr__"] = builtinFunc{
|
|
||||||
"__repr__",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
colored := false
|
|
||||||
if len(a) == 1 {
|
|
||||||
if typeof(a[0]) != "boolean" {
|
|
||||||
return nil, ArErr{"Type Error", "expected boolean, got " + typeof(a[0]), 0, "", "", true}
|
|
||||||
}
|
|
||||||
colored = a[0].(bool)
|
|
||||||
}
|
|
||||||
output := []string{}
|
|
||||||
quoted := strconv.Quote(str)
|
|
||||||
if colored {
|
|
||||||
output = append(output, color.New(33).Sprint(quoted))
|
|
||||||
} else {
|
|
||||||
output = append(output, quoted)
|
|
||||||
}
|
|
||||||
return ArString(strings.Join(output, "")), ArErr{}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +81,7 @@ 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{
|
||||||
@@ -130,19 +90,9 @@ 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 || len(a) == 0 {
|
if len(a) > 3 {
|
||||||
return nil, ArErr{"TypeError", "expected 1 to 3 arguments, got " + fmt.Sprint(len(a)), 0, "", "", true}
|
return nil, ArErr{"TypeError", "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
|
||||||
@@ -151,12 +101,14 @@ func ArString(str string) ArObject {
|
|||||||
{
|
{
|
||||||
if a[0] == nil {
|
if a[0] == nil {
|
||||||
start = 0
|
start = 0
|
||||||
} else if x, ok := a[0].(ArObject); ok {
|
} else if typeof(a[0]) != "number" || !a[0].(number).IsInt() {
|
||||||
start64, err := numberToInt64(x)
|
return "", ArErr{
|
||||||
if err != nil {
|
TYPE: "TypeError",
|
||||||
return nil, ArErr{"Type Error", err.Error(), 0, "", "", true}
|
message: "slice index must be an integer",
|
||||||
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
start = int(start64)
|
} else {
|
||||||
|
start = int(a[0].(number).Num().Int64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(a) > 1 {
|
if len(a) > 1 {
|
||||||
@@ -229,6 +181,7 @@ 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{
|
||||||
@@ -249,6 +202,7 @@ 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{}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -273,6 +227,7 @@ 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{
|
||||||
@@ -299,7 +254,7 @@ func ArString(str string) ArObject {
|
|||||||
if typeof(a[0]) != "string" {
|
if typeof(a[0]) != "string" {
|
||||||
return nil, ArErr{"TypeError", "expected string, got " + typeof(a[0]), 0, "", "", true}
|
return nil, ArErr{"TypeError", "expected string, got " + typeof(a[0]), 0, "", "", true}
|
||||||
}
|
}
|
||||||
splitby := ArValidToAny(a[0]).(string)
|
splitby := a[0].(ArObject).obj["__value__"].(string)
|
||||||
output := []any{}
|
output := []any{}
|
||||||
splitted := (strings.Split(str, splitby))
|
splitted := (strings.Split(str, splitby))
|
||||||
for _, v := range splitted {
|
for _, v := range splitted {
|
||||||
@@ -307,27 +262,6 @@ func ArString(str string) ArObject {
|
|||||||
}
|
}
|
||||||
return output, ArErr{}
|
return output, ArErr{}
|
||||||
}}
|
}}
|
||||||
obj.obj["splitN"] = builtinFunc{
|
|
||||||
"splitN",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 2 {
|
|
||||||
return nil, ArErr{"Type Error", "expected 2 or more argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
|
|
||||||
}
|
|
||||||
if typeof(a[0]) != "string" {
|
|
||||||
return nil, ArErr{"Type Error", "expected string, got " + typeof(a[0]), 0, "", "", true}
|
|
||||||
}
|
|
||||||
if typeof(a[1]) != "number" || !a[1].(number).IsInt() {
|
|
||||||
return nil, ArErr{"Type Error", "expected integer, got " + typeof(a[1]), 0, "", "", true}
|
|
||||||
}
|
|
||||||
splitby := ArValidToAny(a[0]).(string)
|
|
||||||
n := int(a[1].(number).Num().Int64())
|
|
||||||
output := []any{}
|
|
||||||
splitted := (strings.SplitN(str, splitby, n))
|
|
||||||
for _, v := range splitted {
|
|
||||||
output = append(output, ArString(v))
|
|
||||||
}
|
|
||||||
return output, ArErr{}
|
|
||||||
}}
|
|
||||||
obj.obj["capitalise"] = builtinFunc{
|
obj.obj["capitalise"] = builtinFunc{
|
||||||
"capitalise",
|
"capitalise",
|
||||||
func(a ...any) (any, ArErr) {
|
func(a ...any) (any, ArErr) {
|
||||||
@@ -484,6 +418,7 @@ func ArString(str string) ArObject {
|
|||||||
bytes[i] = b.(byte)
|
bytes[i] = b.(byte)
|
||||||
}
|
}
|
||||||
str = string(bytes)
|
str = string(bytes)
|
||||||
|
obj.obj["length"] = len(str)
|
||||||
obj.obj["__value__"] = str
|
obj.obj["__value__"] = str
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}
|
}
|
||||||
@@ -503,6 +438,7 @@ func ArString(str string) ArObject {
|
|||||||
bytes[i] = b.(byte)
|
bytes[i] = b.(byte)
|
||||||
}
|
}
|
||||||
str = string(bytes)
|
str = string(bytes)
|
||||||
|
obj.obj["length"] = len(str)
|
||||||
obj.obj["__value__"] = str
|
obj.obj["__value__"] = str
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
},
|
},
|
||||||
@@ -629,19 +565,7 @@ func ArString(str string) ArObject {
|
|||||||
if typeof(a[0]) != "string" {
|
if typeof(a[0]) != "string" {
|
||||||
a[0] = anyToArgon(a[0], false, false, 3, 0, false, 0)
|
a[0] = anyToArgon(a[0], false, false, 3, 0, false, 0)
|
||||||
}
|
}
|
||||||
return str + a[0].(string), ArErr{}
|
return strings.Join([]string{str, a[0].(string)}, ""), ArErr{}
|
||||||
}}
|
|
||||||
obj.obj["__PostAdd__"] = builtinFunc{
|
|
||||||
"__PostAdd__",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
if len(a) != 1 {
|
|
||||||
return nil, ArErr{"Type Error", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
if typeof(a[0]) != "string" {
|
|
||||||
a[0] = anyToArgon(a[0], false, false, 3, 0, false, 0)
|
|
||||||
}
|
|
||||||
return a[0].(string) + str, ArErr{}
|
|
||||||
}}
|
}}
|
||||||
obj.obj["__Multiply__"] = builtinFunc{
|
obj.obj["__Multiply__"] = builtinFunc{
|
||||||
"__Multiply__",
|
"__Multiply__",
|
||||||
@@ -661,18 +585,6 @@ func ArString(str string) ArObject {
|
|||||||
}
|
}
|
||||||
return strings.Repeat(str, int(n.Num().Int64())), ArErr{}
|
return strings.Repeat(str, int(n.Num().Int64())), ArErr{}
|
||||||
}}
|
}}
|
||||||
obj.obj["__NotContains__"] = builtinFunc{
|
|
||||||
"__NotContains__",
|
|
||||||
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]) != "string" {
|
|
||||||
return nil, ArErr{"Type Error", "cannot check if string contains " + typeof(a[0]), 0, "", "", true}
|
|
||||||
}
|
|
||||||
a[0] = ArValidToAny(a[0])
|
|
||||||
return !strings.Contains(str, a[0].(string)), ArErr{}
|
|
||||||
}}
|
|
||||||
obj.obj["__Contains__"] = builtinFunc{
|
obj.obj["__Contains__"] = builtinFunc{
|
||||||
"__Contains__",
|
"__Contains__",
|
||||||
func(a ...any) (any, ArErr) {
|
func(a ...any) (any, ArErr) {
|
||||||
@@ -715,10 +627,5 @@ func ArString(str string) ArObject {
|
|||||||
}
|
}
|
||||||
return ArArray(output), ArErr{}
|
return ArArray(output), ArErr{}
|
||||||
}}
|
}}
|
||||||
obj.obj["__Boolean__"] = builtinFunc{
|
|
||||||
"__Boolean__",
|
|
||||||
func(a ...any) (any, ArErr) {
|
|
||||||
return len(str) > 0, ArErr{}
|
|
||||||
}}
|
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var timing = anymap{}
|
var timing = anymap{}
|
||||||
var timingSync = sync.RWMutex{}
|
|
||||||
|
|
||||||
var ArTerm = Map(anymap{
|
var ArTerm = Map(anymap{
|
||||||
"log": builtinFunc{"log", func(args ...any) (any, ArErr) {
|
"log": builtinFunc{"log", func(args ...any) (any, ArErr) {
|
||||||
@@ -80,7 +78,7 @@ var ArTerm = Map(anymap{
|
|||||||
}},
|
}},
|
||||||
}),
|
}),
|
||||||
"error": builtinFunc{"error", func(args ...any) (any, ArErr) {
|
"error": builtinFunc{"error", func(args ...any) (any, ArErr) {
|
||||||
output := []any{}
|
output := []any{"error: "}
|
||||||
for i := 0; i < len(args); i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
output = append(output, anyToArgon(args[i], false, true, 3, 0, false, 0))
|
output = append(output, anyToArgon(args[i], false, true, 3, 0, false, 0))
|
||||||
}
|
}
|
||||||
@@ -89,7 +87,7 @@ var ArTerm = Map(anymap{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"warn": builtinFunc{"error", func(args ...any) (any, ArErr) {
|
"warn": builtinFunc{"error", func(args ...any) (any, ArErr) {
|
||||||
output := []any{}
|
output := []any{"warning: "}
|
||||||
for i := 0; i < len(args); i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
output = append(output, anyToArgon(args[i], false, true, 3, 0, false, 0))
|
output = append(output, anyToArgon(args[i], false, true, 3, 0, false, 0))
|
||||||
}
|
}
|
||||||
@@ -102,9 +100,7 @@ var ArTerm = Map(anymap{
|
|||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
id = ArValidToAny(args[0])
|
id = ArValidToAny(args[0])
|
||||||
}
|
}
|
||||||
timingSync.Lock()
|
|
||||||
timing[id] = time.Now()
|
timing[id] = time.Now()
|
||||||
timingSync.Unlock()
|
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -113,15 +109,11 @@ var ArTerm = Map(anymap{
|
|||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
id = ArValidToAny(args[0])
|
id = ArValidToAny(args[0])
|
||||||
}
|
}
|
||||||
timingSync.RLock()
|
|
||||||
if _, ok := timing[id]; !ok {
|
if _, ok := timing[id]; !ok {
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot find timer with id '" + fmt.Sprint(id) + "'", EXISTS: true}
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot find timer with id '" + fmt.Sprint(id) + "'", EXISTS: true}
|
||||||
}
|
}
|
||||||
timesince := time.Since(timing[id].(time.Time))
|
timesince := time.Since(timing[id].(time.Time))
|
||||||
timingSync.RUnlock()
|
|
||||||
timingSync.Lock()
|
|
||||||
delete(timing, id)
|
delete(timing, id)
|
||||||
timingSync.Unlock()
|
|
||||||
if id == nil {
|
if id == nil {
|
||||||
id = "Timer"
|
id = "Timer"
|
||||||
}
|
}
|
||||||
@@ -139,16 +131,11 @@ var ArInput = Map(
|
|||||||
}
|
}
|
||||||
return ArString(resp), ArErr{}
|
return ArString(resp), ArErr{}
|
||||||
}},
|
}},
|
||||||
"__call__": builtinFunc{"input", func(args ...any) (any, ArErr) {
|
|
||||||
resp, err := input(args...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
|
||||||
}
|
|
||||||
return ArString(resp), ArErr{}
|
|
||||||
}},
|
|
||||||
"pause": builtinFunc{"pause", func(args ...any) (any, ArErr) {
|
|
||||||
pause()
|
|
||||||
return nil, ArErr{}
|
|
||||||
}},
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ArInput.obj["__call__"] = builtinFunc{"input", func(args ...any) (any, ArErr) {
|
||||||
|
return input(args...), ArErr{}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var threadChan = sync.WaitGroup{}
|
|
||||||
|
|
||||||
func ArThread(args ...any) (any, ArErr) {
|
func ArThread(args ...any) (any, ArErr) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Invalid number of arguments, expected 1, got " + fmt.Sprint(len(args)), EXISTS: true}
|
return nil, ArErr{TYPE: "TypeError", message: "Invalid number of arguments, expected 1, got " + fmt.Sprint(len(args)), EXISTS: true}
|
||||||
@@ -28,7 +26,7 @@ func ArThread(args ...any) (any, ArErr) {
|
|||||||
|
|
||||||
hasrun := false
|
hasrun := false
|
||||||
joined := false
|
joined := false
|
||||||
var wg = sync.WaitGroup{}
|
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 {
|
||||||
@@ -39,11 +37,9 @@ func ArThread(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
hasrun = true
|
hasrun = true
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
threadChan.Add(1)
|
|
||||||
go func() {
|
go func() {
|
||||||
resp, err = runCall(call{Callable: tocall, Args: []any{}}, nil, 0)
|
resp, err = runCall(call{tocall, []any{}, "", 0, ""}, nil, 0)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
threadChan.Done()
|
|
||||||
}()
|
}()
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}},
|
}},
|
||||||
|
|||||||
19
src/time.go
19
src/time.go
@@ -102,14 +102,11 @@ func ArTimeClass(N time.Time) ArObject {
|
|||||||
|
|
||||||
var ArTime = Map(anymap{
|
var ArTime = Map(anymap{
|
||||||
"snooze": builtinFunc{"snooze", func(a ...any) (any, ArErr) {
|
"snooze": builtinFunc{"snooze", func(a ...any) (any, ArErr) {
|
||||||
if len(a) == 1 {
|
if len(a) > 0 {
|
||||||
float, _ := a[0].(number).Float64()
|
float, _ := a[0].(number).Float64()
|
||||||
time.Sleep(time.Duration(float*1000000000) * time.Nanosecond)
|
time.Sleep(time.Duration(float*1000000000) * time.Nanosecond)
|
||||||
}
|
}
|
||||||
return nil, ArErr{
|
return nil, ArErr{}
|
||||||
TYPE: "Runtime Error",
|
|
||||||
message: "snooze requires 1 argument",
|
|
||||||
}
|
|
||||||
}},
|
}},
|
||||||
"now": builtinFunc{"now", func(a ...any) (any, ArErr) {
|
"now": builtinFunc{"now", func(a ...any) (any, ArErr) {
|
||||||
return ArTimeClass(time.Now()), ArErr{}
|
return ArTimeClass(time.Now()), ArErr{}
|
||||||
@@ -132,7 +129,7 @@ var ArTime = Map(anymap{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ArTimeClass(N), ArErr{}
|
return ArTimeClass(N), ArErr{}
|
||||||
} else if len(a) == 2 {
|
} else if len(a) > 1 {
|
||||||
if typeof(a[0]) != "string" {
|
if typeof(a[0]) != "string" {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "Runtime Error",
|
||||||
@@ -166,7 +163,7 @@ var ArTime = Map(anymap{
|
|||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
"parseInLocation": builtinFunc{"parseInLocation", func(a ...any) (any, ArErr) {
|
"parseInLocation": builtinFunc{"parseInLocation", func(a ...any) (any, ArErr) {
|
||||||
if len(a) == 2 {
|
if len(a) != 2 {
|
||||||
if typeof(a[0]) != "string" || typeof(a[1]) != "string" {
|
if typeof(a[0]) != "string" || typeof(a[1]) != "string" {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "Runtime Error",
|
||||||
@@ -194,7 +191,7 @@ var ArTime = Map(anymap{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"date": builtinFunc{"date", func(a ...any) (any, ArErr) {
|
"date": builtinFunc{"date", func(a ...any) (any, ArErr) {
|
||||||
if len(a) == 1 {
|
if len(a) != 1 {
|
||||||
if typeof(a[0]) != "string" {
|
if typeof(a[0]) != "string" {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "Runtime Error",
|
||||||
@@ -221,7 +218,7 @@ var ArTime = Map(anymap{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"unix": builtinFunc{"unix", func(a ...any) (any, ArErr) {
|
"unix": builtinFunc{"unix", func(a ...any) (any, ArErr) {
|
||||||
if len(a) == 2 {
|
if len(a) != 2 {
|
||||||
if typeof(a[0]) != "number" || typeof(a[1]) != "number" {
|
if typeof(a[0]) != "number" || typeof(a[1]) != "number" {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "Runtime Error",
|
||||||
@@ -241,7 +238,7 @@ var ArTime = Map(anymap{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"unixMilli": builtinFunc{"unixMilli", func(a ...any) (any, ArErr) {
|
"unixMilli": builtinFunc{"unixMilli", func(a ...any) (any, ArErr) {
|
||||||
if len(a) == 1 {
|
if len(a) != 1 {
|
||||||
if typeof(a[0]) != "number" {
|
if typeof(a[0]) != "number" {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "Runtime Error",
|
||||||
@@ -260,7 +257,7 @@ var ArTime = Map(anymap{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"unixMicro": builtinFunc{"unixMicro", func(a ...any) (any, ArErr) {
|
"unixMicro": builtinFunc{"unixMicro", func(a ...any) (any, ArErr) {
|
||||||
if len(a) == 1 {
|
if len(a) > 0 {
|
||||||
if typeof(a[0]) != "number" {
|
if typeof(a[0]) != "number" {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "Runtime Error",
|
TYPE: "Runtime Error",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -10,7 +11,8 @@ import (
|
|||||||
"github.com/jwalton/go-supportscolor"
|
"github.com/jwalton/go-supportscolor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func anyToArgon(x any, representive bool, simplify bool, depth int, indent int, colored bool, plain int) string {
|
func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored bool, plain int) string {
|
||||||
|
x = ArValidToAny(x)
|
||||||
output := []string{}
|
output := []string{}
|
||||||
maybenewline := ""
|
maybenewline := ""
|
||||||
if plain == 1 {
|
if plain == 1 {
|
||||||
@@ -28,9 +30,37 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
|
|||||||
return strings.Join(output, "")
|
return strings.Join(output, "")
|
||||||
}
|
}
|
||||||
switch x := x.(type) {
|
switch x := x.(type) {
|
||||||
|
case string:
|
||||||
|
if !quote {
|
||||||
|
output = append(output, x)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
quoted := strconv.Quote(x)
|
||||||
|
if colored {
|
||||||
|
output = append(output, color.New(33).Sprint(quoted))
|
||||||
|
} else {
|
||||||
|
output = append(output, quoted)
|
||||||
|
}
|
||||||
|
case number:
|
||||||
|
if colored {
|
||||||
|
output = append(output, "\x1b[34;5;240m")
|
||||||
|
}
|
||||||
|
num, _ := x.Float64()
|
||||||
|
if math.IsNaN(num) {
|
||||||
|
output = append(output, "NaN")
|
||||||
|
} else if math.IsInf(num, 1) {
|
||||||
|
output = append(output, "infinity")
|
||||||
|
} else if math.IsInf(num, -1) {
|
||||||
|
output = append(output, "-infinity")
|
||||||
|
} else {
|
||||||
|
output = append(output, numberToString(x, simplify))
|
||||||
|
}
|
||||||
|
if colored {
|
||||||
|
output = append(output, "\x1b[0m")
|
||||||
|
}
|
||||||
case bool:
|
case bool:
|
||||||
if colored {
|
if colored {
|
||||||
output = append(output, "\x1b[35;5;25m")
|
output = append(output, "\x1b[35;5;240m")
|
||||||
}
|
}
|
||||||
output = append(output, strconv.FormatBool(x))
|
output = append(output, strconv.FormatBool(x))
|
||||||
if colored {
|
if colored {
|
||||||
@@ -38,44 +68,12 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
|
|||||||
}
|
}
|
||||||
case nil:
|
case nil:
|
||||||
if colored {
|
if colored {
|
||||||
output = append(output, "\x1b[31;5;25m")
|
output = append(output, "\x1b[31;5;240m")
|
||||||
}
|
}
|
||||||
output = append(output, "null")
|
output = append(output, "null")
|
||||||
if colored {
|
if colored {
|
||||||
output = append(output, "\x1b[0m")
|
output = append(output, "\x1b[0m")
|
||||||
}
|
}
|
||||||
case ArObject:
|
|
||||||
if callable, ok := x.obj["__string__"]; ok && !representive {
|
|
||||||
val, err := runCall(
|
|
||||||
call{
|
|
||||||
Callable: callable,
|
|
||||||
Args: []any{},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if !err.EXISTS {
|
|
||||||
output = append(output, fmt.Sprint(ArValidToAny(val)))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if callable, ok := x.obj["__repr__"]; ok {
|
|
||||||
val, err := runCall(
|
|
||||||
call{
|
|
||||||
Callable: callable,
|
|
||||||
Args: []any{colored},
|
|
||||||
},
|
|
||||||
stack{},
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if !err.EXISTS {
|
|
||||||
output = append(output, fmt.Sprint(ArValidToAny(val)))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if val, ok := x.obj["__value__"]; ok {
|
|
||||||
output = append(output, anyToArgon(val, representive, simplify, depth, indent, colored, plain))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
output = append(output, "<object>")
|
|
||||||
case anymap:
|
case anymap:
|
||||||
if len(x) == 0 {
|
if len(x) == 0 {
|
||||||
return "{}"
|
return "{}"
|
||||||
@@ -99,7 +97,7 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
|
|||||||
} else {
|
} else {
|
||||||
outputkeyval := []string{}
|
outputkeyval := []string{}
|
||||||
if colored {
|
if colored {
|
||||||
outputkeyval = append(outputkeyval, "\x1b[36;5;25m")
|
outputkeyval = append(outputkeyval, "\x1b[36;5;240m")
|
||||||
}
|
}
|
||||||
outputkeyval = append(outputkeyval, key.(string))
|
outputkeyval = append(outputkeyval, key.(string))
|
||||||
if colored {
|
if colored {
|
||||||
@@ -119,7 +117,7 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
|
|||||||
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;25m(...)\x1b[0m")
|
output = append(output, "\x1b[38;5;240m(...)\x1b[0m")
|
||||||
} else {
|
} else {
|
||||||
output = append(output, "(...)")
|
output = append(output, "(...)")
|
||||||
}
|
}
|
||||||
@@ -144,7 +142,7 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
|
|||||||
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;25m")
|
output = append(output, "\x1b[38;5;240m")
|
||||||
}
|
}
|
||||||
output = append(output, "<builtin function "+x.name+">")
|
output = append(output, "<builtin function "+x.name+">")
|
||||||
if colored {
|
if colored {
|
||||||
@@ -152,7 +150,7 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
|
|||||||
}
|
}
|
||||||
case Callable:
|
case Callable:
|
||||||
if colored {
|
if colored {
|
||||||
output = append(output, "\x1b[38;5;25m")
|
output = append(output, "\x1b[38;5;240m")
|
||||||
}
|
}
|
||||||
output = append(output, "<function "+x.name+">")
|
output = append(output, "<function "+x.name+">")
|
||||||
if colored {
|
if colored {
|
||||||
|
|||||||
130
src/translate.go
130
src/translate.go
@@ -11,8 +11,6 @@ type UNPARSEcode struct {
|
|||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
var (
|
var (
|
||||||
resp any = nil
|
resp any = nil
|
||||||
@@ -20,144 +18,115 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
|||||||
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 == 2 {
|
||||||
if isComment(code) {
|
if isDeleteVariable(code) {
|
||||||
|
return parseDelete(code, index, codelines)
|
||||||
|
} else 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 isReturn(code) {
|
||||||
if isIfStatement(code) {
|
return parseReturn(code, index, codelines)
|
||||||
|
} else if isBreak(code) {
|
||||||
|
return parseBreak(code)
|
||||||
|
} else if isContinue(code) {
|
||||||
|
return parseContinue(code)
|
||||||
|
} else if isIfStatement(code) {
|
||||||
return parseIfStatement(code, index, codelines)
|
return parseIfStatement(code, index, codelines)
|
||||||
} else if isWhileLoop(code) {
|
} else if isWhileLoop(code) {
|
||||||
return parseWhileLoop(code, index, codelines)
|
return parseWhileLoop(code, index, codelines)
|
||||||
} else if isForeverLoop(code) {
|
} else if isForeverLoop(code) {
|
||||||
return parseForeverLoop(code, index, codelines)
|
return parseForeverLoop(code, index, codelines)
|
||||||
|
|
||||||
} else if isForLoop(code) {
|
} else if isForLoop(code) {
|
||||||
return parseForLoop(code, index, codelines)
|
return parseForLoop(code, index, codelines)
|
||||||
|
|
||||||
} else if isGenericImport(code) {
|
} else if isGenericImport(code) {
|
||||||
return parseGenericImport(code, index, codelines)
|
return parseGenericImport(code, index, codelines)
|
||||||
|
|
||||||
} else if isTryCatch(code) {
|
} else if isTryCatch(code) {
|
||||||
return parseTryCatch(code, index, codelines)
|
return parseTryCatch(code, index, codelines)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if isLine >= 1 {
|
||||||
if isLine >= 2 {
|
if isDoWrap(code) {
|
||||||
if isReturn(code) {
|
return parseDoWrap(code, index, codelines)
|
||||||
return parseReturn(code, index, codelines)
|
|
||||||
|
|
||||||
} else if isBreak(code) {
|
|
||||||
return parseBreak(code)
|
|
||||||
|
|
||||||
} else if isContinue(code) {
|
|
||||||
return parseContinue(code)
|
|
||||||
|
|
||||||
} else if isDeleteVariable(code) {
|
|
||||||
return parseDelete(code, index, codelines)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isLine > 1 {
|
if isLine == 2 {
|
||||||
isLine = 1
|
isLine = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if isDoWrap(code) {
|
if isBoolean(code) {
|
||||||
return parseDoWrap(code, index, codelines)
|
|
||||||
} else if isBoolean(code) {
|
|
||||||
return parseBoolean(code)
|
return parseBoolean(code)
|
||||||
} else if !QuickKnownFailures["brackets"+code.code] && isBrackets(code) {
|
} else if 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 !QuickKnownFailures["abs"+code.code] && isAbs(code) {
|
if 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 !QuickKnownFailures["autoasign"+code.code] && isAutoAsignVariable(code) {
|
if isnot(code) {
|
||||||
|
return parseNot(code, index, codelines, isLine)
|
||||||
|
}
|
||||||
|
if isSetVariable(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 isSetVariable(code) {
|
if isNumber(code) {
|
||||||
return parseSetVariable(code, index, codelines, isLine)
|
|
||||||
} else if isNumber(code) {
|
|
||||||
return parseNumber(code)
|
return parseNumber(code)
|
||||||
} else if isString(code) {
|
} else if isString(code) {
|
||||||
return parseString(code)
|
return parseString(code)
|
||||||
} else if !QuickKnownFailures["squareroot"+code.code] && issquareroot(code) {
|
} else if issquareroot(code) {
|
||||||
resp, worked, err, i = parseSquareroot(code, index, codelines)
|
return parseSquareroot(code, index, codelines)
|
||||||
if worked {
|
} else if isFactorial(code) {
|
||||||
return resp, worked, err, i
|
return parseFactorial(code, index, codelines)
|
||||||
}
|
|
||||||
QuickKnownFailures["squareroot"+code.code] = true
|
|
||||||
}
|
}
|
||||||
if isVariable(code) {
|
if isVariable(code) {
|
||||||
return parseVariable(code)
|
return parseVariable(code)
|
||||||
}
|
}
|
||||||
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) {
|
|
||||||
resp, worked, err, i = parseMap(code, index, codelines)
|
|
||||||
}
|
}
|
||||||
if !QuickKnownFailures["not"+code.code] && isnot(code) {
|
if isCall(code) {
|
||||||
resp, worked, err, i = parseNot(code, index, codelines, isLine)
|
|
||||||
if worked {
|
|
||||||
return resp, worked, err, i
|
|
||||||
}
|
|
||||||
QuickKnownFailures["not"+code.code] = true
|
|
||||||
}
|
|
||||||
if !QuickKnownFailures["operations"+code.code] {
|
|
||||||
operation, worked, err, step := parseOperations(code, index, codelines)
|
|
||||||
if worked {
|
|
||||||
return operation, worked, err, step
|
|
||||||
}
|
|
||||||
QuickKnownFailures["operations"+code.code] = true
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, worked, err, step
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !QuickKnownFailures["factorial"+code.code] && isFactorial(code) {
|
|
||||||
resp, worked, err, i = parseFactorial(code, index, codelines)
|
|
||||||
if worked {
|
|
||||||
return resp, worked, err, i
|
|
||||||
}
|
|
||||||
QuickKnownFailures["factorial"+code.code] = true
|
|
||||||
}
|
|
||||||
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
|
}
|
||||||
|
{
|
||||||
|
operation, worked, err, step := parseOperations(code, index, codelines)
|
||||||
|
if worked {
|
||||||
|
return operation, worked, err, step
|
||||||
|
} else if err.EXISTS {
|
||||||
|
return nil, worked, err, step
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if isNegative(code) {
|
if isNegative(code) {
|
||||||
return parseNegative(code, index, codelines)
|
return parseNegative(code, index, codelines)
|
||||||
} else if isMapGet(code) {
|
} else if isMapGet(code) {
|
||||||
return mapGetParse(code, index, codelines)
|
return mapGetParse(code, index, codelines)
|
||||||
} else if !QuickKnownFailures["indexget"+code.code] && isIndexGet(code) {
|
} 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, worked, err, i
|
return resp, worked, err, i
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,16 +141,15 @@ 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, 4)
|
val, _, err, step := translateVal(codelines[i], i, codelines, 2)
|
||||||
|
switch val.(type) {
|
||||||
|
case CallReturn:
|
||||||
|
return nil, ArErr{"Runtime Error", "Jump statment at top level", codelines[i].line, codelines[i].path, codelines[i].realcode, true}
|
||||||
|
}
|
||||||
i += step
|
i += step
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = translateThrowOnNonLoop(val)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
translated = append(translated, val)
|
translated = append(translated, val)
|
||||||
}
|
}
|
||||||
return translated, ArErr{}
|
return translated, ArErr{}
|
||||||
|
|||||||
57
src/trig.go
57
src/trig.go
@@ -7,18 +7,6 @@ import (
|
|||||||
|
|
||||||
var PIFloatInaccuracy number = newNumber()
|
var PIFloatInaccuracy number = newNumber()
|
||||||
|
|
||||||
type sinCacheValue struct {
|
|
||||||
INPUT number
|
|
||||||
OUTPUT number
|
|
||||||
}
|
|
||||||
|
|
||||||
var sinCache = []sinCacheValue{
|
|
||||||
{newNumber(), newNumber()},
|
|
||||||
{newNumber().Quo(PI_RAT, newNumber().SetInt64(2)), newNumber().SetInt64(1)},
|
|
||||||
{PI_RAT, newNumber()},
|
|
||||||
{newNumber().Add(PI_RAT, newNumber().Quo(PI_RAT, newNumber().SetInt64(2))), newNumber().SetInt64(-1)},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
PIFloatInaccuracy.SetFloat64(math.Asin(1) * 2)
|
PIFloatInaccuracy.SetFloat64(math.Asin(1) * 2)
|
||||||
}
|
}
|
||||||
@@ -37,19 +25,7 @@ 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_RAT, newNumber().SetInt64(2))
|
num.Quo(num, PI)
|
||||||
toTrim.Quo(num, toTrim)
|
|
||||||
toTrim = floor(toTrim)
|
|
||||||
toTrim.Mul(toTrim, newNumber().Mul(PI_RAT, 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_RAT)
|
|
||||||
num.Mul(num, PIFloatInaccuracy)
|
num.Mul(num, PIFloatInaccuracy)
|
||||||
n, _ := num.Float64()
|
n, _ := num.Float64()
|
||||||
outputnum := newNumber().SetFloat64(math.Sin(n))
|
outputnum := newNumber().SetFloat64(math.Sin(n))
|
||||||
@@ -78,7 +54,7 @@ var ArArcsin = builtinFunc{"arcsin", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
outputnum := newNumber().SetFloat64(math.Asin(n))
|
outputnum := newNumber().SetFloat64(math.Asin(n))
|
||||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||||
outputnum.Mul(outputnum, PI_RAT)
|
outputnum.Mul(outputnum, PI)
|
||||||
return outputnum, ArErr{}
|
return outputnum, ArErr{}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -95,7 +71,12 @@ var ArCos = builtinFunc{"cos", func(args ...any) (any, ArErr) {
|
|||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builtinCall(ArSin, []any{newNumber().Add(args[0].(number), newNumber().Quo(PI_RAT, newNumber().SetInt64(2)))})
|
num := newNumber().Set(args[0].(number))
|
||||||
|
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 {
|
||||||
@@ -120,7 +101,7 @@ var ArArccos = builtinFunc{"arccos", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
outputnum := newNumber().SetFloat64(math.Acos(n))
|
outputnum := newNumber().SetFloat64(math.Acos(n))
|
||||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||||
outputnum.Mul(outputnum, PI_RAT)
|
outputnum.Mul(outputnum, PI)
|
||||||
return outputnum, ArErr{}
|
return outputnum, ArErr{}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -138,7 +119,7 @@ var ArTan = builtinFunc{"tan", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
num := newNumber().Set(args[0].(number))
|
num := newNumber().Set(args[0].(number))
|
||||||
num.Quo(num, PI_RAT)
|
num.Quo(num, PI)
|
||||||
num.Mul(num, PIFloatInaccuracy)
|
num.Mul(num, PIFloatInaccuracy)
|
||||||
n, _ := num.Float64()
|
n, _ := num.Float64()
|
||||||
outputnum := newNumber().SetFloat64(math.Tan(n))
|
outputnum := newNumber().SetFloat64(math.Tan(n))
|
||||||
@@ -161,7 +142,7 @@ var ArArctan = builtinFunc{"arctan", func(args ...any) (any, ArErr) {
|
|||||||
n, _ := num.Float64()
|
n, _ := num.Float64()
|
||||||
outputnum := newNumber().SetFloat64(math.Atan(n))
|
outputnum := newNumber().SetFloat64(math.Atan(n))
|
||||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||||
outputnum.Mul(outputnum, PI_RAT)
|
outputnum.Mul(outputnum, PI)
|
||||||
return outputnum, ArErr{}
|
return outputnum, ArErr{}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -179,7 +160,7 @@ var ArCosec = builtinFunc{"cosec", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
num := newNumber().Set(args[0].(number))
|
num := newNumber().Set(args[0].(number))
|
||||||
num.Quo(num, PI_RAT)
|
num.Quo(num, PI)
|
||||||
num.Mul(num, PIFloatInaccuracy)
|
num.Mul(num, PIFloatInaccuracy)
|
||||||
n, _ := num.Float64()
|
n, _ := num.Float64()
|
||||||
outputnum := newNumber().SetFloat64(1 / math.Sin(n))
|
outputnum := newNumber().SetFloat64(1 / math.Sin(n))
|
||||||
@@ -208,7 +189,7 @@ var ArArccosec = builtinFunc{"arccosec", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
outputnum := newNumber().SetFloat64(math.Asin(1 / n))
|
outputnum := newNumber().SetFloat64(math.Asin(1 / n))
|
||||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||||
outputnum.Mul(outputnum, PI_RAT)
|
outputnum.Mul(outputnum, PI)
|
||||||
return outputnum, ArErr{}
|
return outputnum, ArErr{}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -226,7 +207,7 @@ var ArSec = builtinFunc{"sec", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
num := newNumber().Set(args[0].(number))
|
num := newNumber().Set(args[0].(number))
|
||||||
num.Quo(num, PI_RAT)
|
num.Quo(num, PI)
|
||||||
num.Mul(num, PIFloatInaccuracy)
|
num.Mul(num, PIFloatInaccuracy)
|
||||||
n, _ := num.Float64()
|
n, _ := num.Float64()
|
||||||
outputnum := newNumber().SetFloat64(1 / math.Cos(n))
|
outputnum := newNumber().SetFloat64(1 / math.Cos(n))
|
||||||
@@ -256,7 +237,7 @@ var ArArcsec = builtinFunc{"arcsec", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
outputnum := newNumber().SetFloat64(math.Acos(1 / n))
|
outputnum := newNumber().SetFloat64(math.Acos(1 / n))
|
||||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||||
outputnum.Mul(outputnum, PI_RAT)
|
outputnum.Mul(outputnum, PI)
|
||||||
return outputnum, ArErr{}
|
return outputnum, ArErr{}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -274,7 +255,7 @@ var ArCot = builtinFunc{"cot", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
num := newNumber().Set(args[0].(number))
|
num := newNumber().Set(args[0].(number))
|
||||||
num.Quo(num, PI_RAT)
|
num.Quo(num, PI)
|
||||||
num.Mul(num, PIFloatInaccuracy)
|
num.Mul(num, PIFloatInaccuracy)
|
||||||
n, _ := num.Float64()
|
n, _ := num.Float64()
|
||||||
outputnum := newNumber().SetFloat64(1 / math.Tan(n))
|
outputnum := newNumber().SetFloat64(1 / math.Tan(n))
|
||||||
@@ -298,7 +279,7 @@ var ArArccot = builtinFunc{"arccot", func(args ...any) (any, ArErr) {
|
|||||||
n, _ := num.Float64()
|
n, _ := num.Float64()
|
||||||
outputnum := newNumber().SetFloat64(math.Atan(1 / n))
|
outputnum := newNumber().SetFloat64(math.Atan(1 / n))
|
||||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||||
outputnum.Mul(outputnum, PI_RAT)
|
outputnum.Mul(outputnum, PI)
|
||||||
return outputnum, ArErr{}
|
return outputnum, ArErr{}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -316,7 +297,7 @@ var ArToDeg = builtinFunc{"toDeg", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
num := newNumber().Set(args[0].(number))
|
num := newNumber().Set(args[0].(number))
|
||||||
num.Quo(num, PI_RAT)
|
num.Quo(num, PI)
|
||||||
num.Mul(num, newNumber().SetInt64(180))
|
num.Mul(num, newNumber().SetInt64(180))
|
||||||
return num, ArErr{}
|
return num, ArErr{}
|
||||||
}}
|
}}
|
||||||
@@ -336,6 +317,6 @@ var ArToRad = builtinFunc{"toRad", func(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
num := newNumber().Set(args[0].(number))
|
num := newNumber().Set(args[0].(number))
|
||||||
num.Quo(num, newNumber().SetInt64(180))
|
num.Quo(num, newNumber().SetInt64(180))
|
||||||
num.Mul(num, PI_RAT)
|
num.Mul(num, PI)
|
||||||
return num, ArErr{}
|
return num, ArErr{}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -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, 3)
|
tryparsed, worked, err, i := translateVal(UNPARSEcode{trytrimmed[4:], code.realcode, code.line, code.path}, index, codelines, 1)
|
||||||
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, 3)
|
catchparsed, worked, err, i := translateVal(UNPARSEcode{errcode, code.realcode, code.line, code.path}, index+totalIndex, codelines, 1)
|
||||||
if !worked {
|
if !worked {
|
||||||
return TryCatch{}, false, err, i
|
return TryCatch{}, false, err, i
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ func parseTryCatch(code UNPARSEcode, index int, codelines []UNPARSEcode) (TryCat
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runTryCatch(t TryCatch, stack stack, stacklevel int) (any, ArErr) {
|
func runTryCatch(t TryCatch, stack stack, stacklevel int) (any, ArErr) {
|
||||||
val, err := runVal(t.Try, stack, stacklevel+1)
|
val, err := runVal(t.Try, stack, stacklevel)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
vars := anymap{}
|
vars := anymap{}
|
||||||
vars[t.errorName] = Map(anymap{
|
vars[t.errorName] = Map(anymap{
|
||||||
@@ -67,7 +67,7 @@ func runTryCatch(t TryCatch, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
"path": err.path,
|
"path": err.path,
|
||||||
"code": err.code,
|
"code": err.code,
|
||||||
})
|
})
|
||||||
val, err = runVal(t.Catch, append(stack, Map(vars)), stacklevel+1)
|
val, err = runVal(t.Catch, append(stack, Map(vars)), stacklevel)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package main
|
|||||||
|
|
||||||
func typeof(val any) string {
|
func typeof(val any) string {
|
||||||
switch x := val.(type) {
|
switch x := val.(type) {
|
||||||
|
case number:
|
||||||
|
return "number"
|
||||||
case nil:
|
case nil:
|
||||||
return "null"
|
return "null"
|
||||||
case bool:
|
case bool:
|
||||||
@@ -16,10 +18,6 @@ func typeof(val any) string {
|
|||||||
return "function"
|
return "function"
|
||||||
case builtinFunc:
|
case builtinFunc:
|
||||||
return "function"
|
return "function"
|
||||||
case byte:
|
|
||||||
return "byte"
|
|
||||||
case []byte:
|
|
||||||
return "buffer"
|
|
||||||
case ArObject:
|
case ArObject:
|
||||||
if val, ok := x.obj["__name__"]; ok {
|
if val, ok := x.obj["__name__"]; ok {
|
||||||
val := ArValidToAny(val)
|
val := ArValidToAny(val)
|
||||||
|
|||||||
100
src/variable.go
100
src/variable.go
@@ -37,10 +37,10 @@ var blockedVariableNames = map[string]bool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
type accessVariable struct {
|
type accessVariable struct {
|
||||||
Name string
|
name string
|
||||||
Line int
|
line int
|
||||||
Code string
|
code string
|
||||||
Path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
type setVariable struct {
|
type setVariable struct {
|
||||||
@@ -72,17 +72,16 @@ func isVariable(code UNPARSEcode) bool {
|
|||||||
|
|
||||||
func parseVariable(code UNPARSEcode) (accessVariable, bool, ArErr, int) {
|
func parseVariable(code UNPARSEcode) (accessVariable, bool, ArErr, int) {
|
||||||
name := strings.TrimSpace(code.code)
|
name := strings.TrimSpace(code.code)
|
||||||
return accessVariable{Name: name, Code: code.realcode, Line: code.line, Path: code.path}, true, ArErr{}, 1
|
return accessVariable{name: name, code: code.realcode, line: code.line, path: code.path}, true, ArErr{}, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
||||||
name := ArString(v.Name)
|
|
||||||
for i := len(stack) - 1; i >= 0; i-- {
|
for i := len(stack) - 1; i >= 0; i-- {
|
||||||
callable, ok := stack[i].obj["__Contains__"]
|
callable, ok := stack[i].obj["__Contains__"]
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
contains, err := builtinCall(callable, []any{name})
|
contains, err := builtinCall(callable, []any{v.name})
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -91,10 +90,10 @@ func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return builtinCall(callable, []any{name})
|
return builtinCall(callable, []any{v.name})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Name Error", "variable \"" + v.Name + "\" does not exist", v.Line, v.Path, v.Code, true}
|
return nil, ArErr{"Name Error", "variable \"" + v.name + "\" does not exist", v.line, v.path, v.code, true}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSetVariable(code UNPARSEcode) bool {
|
func isSetVariable(code UNPARSEcode) bool {
|
||||||
@@ -160,7 +159,7 @@ func parseSetVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine i
|
|||||||
params = x.params
|
params = x.params
|
||||||
toset = x.toset
|
toset = x.toset
|
||||||
if toset == nil {
|
if toset == nil {
|
||||||
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
|
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean to put 'let' before?", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
|
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
|
||||||
@@ -172,47 +171,19 @@ func parseSetVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine i
|
|||||||
return setVariable{TYPE: "let", toset: toset, value: value, function: function, params: params, line: code.line, code: code.code, path: code.path}, true, ArErr{}, i + namei - 1
|
return setVariable{TYPE: "let", toset: toset, value: value, function: function, params: params, line: code.line, code: code.code, path: code.path}, true, ArErr{}, i + namei - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var operationsToInt = map[byte]int{
|
|
||||||
'+': 10,
|
|
||||||
'-': 11,
|
|
||||||
'*': 12,
|
|
||||||
'/': 15,
|
|
||||||
'^': 16,
|
|
||||||
'&': 0,
|
|
||||||
'|': 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseAutoAsignVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine int) (setVariable, bool, ArErr, int) {
|
func parseAutoAsignVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine int) (setVariable, bool, ArErr, int) {
|
||||||
trim := strings.TrimSpace(code.code)
|
trim := strings.TrimSpace(code.code)
|
||||||
equalsplit := strings.Split(trim, "=")
|
equalsplit := strings.SplitN(trim, "=", 2)
|
||||||
for i := 1; i < len(equalsplit); i++ {
|
name := strings.TrimSpace(equalsplit[0])
|
||||||
name := strings.TrimSpace(strings.Join(equalsplit[:i], "="))
|
|
||||||
if name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
operation := name[len(name)-1]
|
|
||||||
var operationtype int = -1
|
|
||||||
if operation == '+' || operation == '-' || operation == '*' || operation == '/' || operation == '^' || operation == '&' || operation == '|' {
|
|
||||||
name = strings.TrimSpace(name[:len(name)-1])
|
|
||||||
if n, ok := operationsToInt[operation]; ok {
|
|
||||||
operationtype = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params := []string{}
|
params := []string{}
|
||||||
function := false
|
function := false
|
||||||
if blockedVariableNames[name] {
|
if blockedVariableNames[name] {
|
||||||
if i == len(equalsplit)-1 {
|
|
||||||
return setVariable{}, false, ArErr{"Naming Error", "\"" + name + "\" is a reserved keyword", code.line, code.path, code.realcode, true}, 1
|
return setVariable{}, false, ArErr{"Naming Error", "\"" + name + "\" is a reserved keyword", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
|
||||||
toset, success, err, namei := nameToTranslated(UNPARSEcode{code: name, realcode: code.realcode, line: code.line, path: code.path}, index, lines)
|
toset, success, err, namei := nameToTranslated(UNPARSEcode{code: name, realcode: code.realcode, line: code.line, path: code.path}, index, lines)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
if i == len(equalsplit)-1 {
|
|
||||||
return setVariable{}, success, err, namei
|
return setVariable{}, success, err, namei
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch x := toset.(type) {
|
switch x := toset.(type) {
|
||||||
case accessVariable:
|
case accessVariable:
|
||||||
break
|
break
|
||||||
@@ -223,28 +194,14 @@ func parseAutoAsignVariable(code UNPARSEcode, index int, lines []UNPARSEcode, is
|
|||||||
params = x.params
|
params = x.params
|
||||||
toset = x.toset
|
toset = x.toset
|
||||||
default:
|
default:
|
||||||
if i == len(equalsplit)-1 {
|
|
||||||
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
|
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
continue
|
value, success, err, i := translateVal(UNPARSEcode{code: equalsplit[1], realcode: code.realcode, line: code.line, path: code.path}, index, lines, isLine)
|
||||||
}
|
|
||||||
value, success, err, i := translateVal(UNPARSEcode{code: strings.Join(equalsplit[i:], "="), realcode: code.realcode, line: code.line, path: code.path}, index, lines, isLine)
|
|
||||||
if !success {
|
if !success {
|
||||||
return setVariable{}, false, err, i
|
return setVariable{}, false, err, i
|
||||||
}
|
}
|
||||||
if operationtype != -1 {
|
|
||||||
value = operationType{
|
|
||||||
operation: operationtype,
|
|
||||||
values: []any{toset, value},
|
|
||||||
line: code.line,
|
|
||||||
code: code.code,
|
|
||||||
path: code.path,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return setVariable{TYPE: "auto", toset: toset, value: value, function: function, params: params, line: code.line, code: code.code, path: code.path}, true, ArErr{}, i + namei - 1
|
return setVariable{TYPE: "auto", toset: toset, value: value, function: function, params: params, line: code.line, code: code.code, path: code.path}, true, ArErr{}, i + namei - 1
|
||||||
}
|
}
|
||||||
return setVariable{}, false, ArErr{"Syntax Error", "invalid syntax", code.line, code.path, code.realcode, true}, 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
||||||
var resp any
|
var resp any
|
||||||
@@ -259,22 +216,18 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if v.TYPE == "let" {
|
if v.TYPE == "let" {
|
||||||
name := v.toset.(accessVariable).Name
|
|
||||||
if v.function {
|
|
||||||
resp = Callable{name, v.params, v.value, v.code, stack, v.line}
|
|
||||||
}
|
|
||||||
stackcallable, ok := stack[len(stack)-1].obj["__setindex__"]
|
stackcallable, ok := stack[len(stack)-1].obj["__setindex__"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ArErr{"Type Error", "stack doesn't have __setindex__", v.line, v.path, v.code, true}
|
return nil, ArErr{"Type Error", "stack doesn't have __setindex__", v.line, v.path, v.code, true}
|
||||||
}
|
}
|
||||||
_, err := builtinCall(stackcallable, []any{name, resp})
|
_, err := builtinCall(stackcallable, []any{v.toset.(accessVariable).name, resp})
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch x := v.toset.(type) {
|
switch x := v.toset.(type) {
|
||||||
case accessVariable:
|
case accessVariable:
|
||||||
name := x.Name
|
name := x.name
|
||||||
hasSet := false
|
hasSet := false
|
||||||
if v.function {
|
if v.function {
|
||||||
resp = Callable{name, v.params, v.value, v.code, stack, v.line}
|
resp = Callable{name, v.params, v.value, v.code, stack, v.line}
|
||||||
@@ -310,10 +263,10 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(x.Args) != 1 {
|
if len(x.args) != 1 {
|
||||||
return nil, ArErr{"Runtime Error", "cannot set by slice", v.line, v.path, v.code, true}
|
return nil, ArErr{"Runtime Error", "cannot set by slice", v.line, v.path, v.code, true}
|
||||||
}
|
}
|
||||||
key, err := runVal(x.Args[0], stack, stacklevel+1)
|
key, err := runVal(x.args[0], stack, stacklevel+1)
|
||||||
key = ArValidToAny(key)
|
key = ArValidToAny(key)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -322,12 +275,13 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
case ArObject:
|
case ArObject:
|
||||||
if _, ok := y.obj["__setindex__"]; ok {
|
if _, ok := y.obj["__setindex__"]; ok {
|
||||||
callable := y.obj["__setindex__"]
|
callable := y.obj["__setindex__"]
|
||||||
|
r := ArValidToAny(resp)
|
||||||
_, err := runCall(call{
|
_, err := runCall(call{
|
||||||
Callable: callable,
|
callable: callable,
|
||||||
Args: []any{key, resp},
|
args: []any{key, r},
|
||||||
Line: v.line,
|
line: v.line,
|
||||||
Path: v.path,
|
path: v.path,
|
||||||
Code: v.code,
|
code: v.code,
|
||||||
}, stack, stacklevel+1)
|
}, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -369,7 +323,7 @@ func runDelete(d ArDelete, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
contains, err := builtinCall(callable, []any{x.Name})
|
contains, err := builtinCall(callable, []any{x.name})
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -378,19 +332,19 @@ func runDelete(d ArDelete, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return builtinCall(callable, []any{x.Name})
|
return builtinCall(callable, []any{x.name})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Name Error", "variable \"" + x.Name + "\" does not exist", d.line, d.path, d.code, true}
|
return nil, ArErr{"Name Error", "variable \"" + x.name + "\" does not exist", d.line, d.path, d.code, true}
|
||||||
case ArMapGet:
|
case ArMapGet:
|
||||||
respp, err := runVal(x.VAL, stack, stacklevel+1)
|
respp, err := runVal(x.VAL, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(x.Args) != 1 {
|
if len(x.args) != 1 {
|
||||||
return nil, ArErr{"Runtime Error", "can't delete by slice", d.line, d.path, d.code, true}
|
return nil, ArErr{"Runtime Error", "can't delete by slice", d.line, d.path, d.code, true}
|
||||||
}
|
}
|
||||||
key, err := runVal(x.Args[0], stack, stacklevel+1)
|
key, err := runVal(x.args[0], stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
221
src/wasm.go
Normal file
221
src/wasm.go
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"syscall/js"
|
||||||
|
)
|
||||||
|
|
||||||
|
func argonToJsValid(argon any) any {
|
||||||
|
switch x := argon.(type) {
|
||||||
|
case number:
|
||||||
|
f, _ := x.Float64()
|
||||||
|
return f
|
||||||
|
case ArObject:
|
||||||
|
if typeof(x) == "array" {
|
||||||
|
arr := js.Global().Get("Array").New()
|
||||||
|
for i, v := range x.obj["__value__"].([]any) {
|
||||||
|
arr.SetIndex(i, argonToJsValid(v))
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
} else if typeof(x) == "string" {
|
||||||
|
return x.obj["__value__"].(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj := js.Global().Get("Object").New()
|
||||||
|
for k, v := range x.obj {
|
||||||
|
obj.Set(anyToArgon(k, false, false, 3, 0, false, 0), argonToJsValid(v))
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
case bool, string:
|
||||||
|
return x
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func wasmRun(code string, allowDocument bool) (any, ArErr) {
|
||||||
|
JSclearTimers()
|
||||||
|
initRandom()
|
||||||
|
global := makeGlobal(allowDocument)
|
||||||
|
lines := strings.Split(code, "\n")
|
||||||
|
codelines := []UNPARSEcode{}
|
||||||
|
for i := 0; i < len(lines); i++ {
|
||||||
|
codelines = append(codelines, UNPARSEcode{
|
||||||
|
lines[i],
|
||||||
|
lines[i],
|
||||||
|
i + 1,
|
||||||
|
"<wasm>",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
translated, translationerr := translate(codelines)
|
||||||
|
if translationerr.EXISTS {
|
||||||
|
return nil, translationerr
|
||||||
|
}
|
||||||
|
local := newscope()
|
||||||
|
localvars := Map(anymap{
|
||||||
|
"program": Map(anymap{
|
||||||
|
"args": []any{},
|
||||||
|
"origin": "",
|
||||||
|
"import": builtinFunc{"import", func(args ...any) (any, ArErr) {
|
||||||
|
return nil, ArErr{"Import Error", "Cannot Import in WASM", 0, "<wasm>", "", true}
|
||||||
|
}},
|
||||||
|
"cwd": "",
|
||||||
|
"exc": "",
|
||||||
|
"file": Map(anymap{
|
||||||
|
"name": "<wasm>",
|
||||||
|
"path": "",
|
||||||
|
}),
|
||||||
|
"main": true,
|
||||||
|
"scope": global,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
return ThrowOnNonLoop(run(translated, stack{global, localvars, local}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func await(awaitable js.Value) ([]js.Value, []js.Value) {
|
||||||
|
then := make(chan []js.Value)
|
||||||
|
defer close(then)
|
||||||
|
thenFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
|
then <- args
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
defer thenFunc.Release()
|
||||||
|
|
||||||
|
catch := make(chan []js.Value)
|
||||||
|
defer close(catch)
|
||||||
|
catchFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
|
catch <- args
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
defer catchFunc.Release()
|
||||||
|
|
||||||
|
awaitable.Call("then", thenFunc).Call("catch", catchFunc)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case result := <-then:
|
||||||
|
return result, nil
|
||||||
|
case err := <-catch:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var IntervalList = []int{}
|
||||||
|
var TimeoutList = []int{}
|
||||||
|
|
||||||
|
func JSclearTimers() {
|
||||||
|
for _, v := range IntervalList {
|
||||||
|
js.Global().Call("clearInterval", v)
|
||||||
|
}
|
||||||
|
for _, v := range TimeoutList {
|
||||||
|
js.Global().Call("clearTimeout", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArJS = Map(anymap{
|
||||||
|
"setTimeout": builtinFunc{"setTimeout", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) > 2 || len(args) < 1 {
|
||||||
|
return nil, ArErr{"TypeError", "Expected 1 or 2 argument, got " + fmt.Sprint(len(args)), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "function" {
|
||||||
|
return nil, ArErr{"TypeError", "Expected function, got " + typeof(args[0]), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
var ms int64 = 0
|
||||||
|
if len(args) == 2 {
|
||||||
|
if typeof(args[1]) != "number" {
|
||||||
|
return nil, ArErr{"TypeError", "Expected number, got " + typeof(args[1]), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
if !args[1].(number).IsInt() {
|
||||||
|
return nil, ArErr{"TypeError", "Expected integer, got float", 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
ms = args[1].(number).Num().Int64()
|
||||||
|
}
|
||||||
|
f := js.FuncOf(func(this js.Value, a []js.Value) interface{} {
|
||||||
|
runCall(
|
||||||
|
call{
|
||||||
|
callable: args[0],
|
||||||
|
args: []any{},
|
||||||
|
},
|
||||||
|
stack{},
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
n := js.Global().Call("setTimeout", f, ms).Int()
|
||||||
|
TimeoutList = append(TimeoutList, n)
|
||||||
|
return newNumber().SetInt64(int64(n)), ArErr{}
|
||||||
|
}},
|
||||||
|
"setInterval": builtinFunc{"setInterval", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) > 2 || len(args) < 1 {
|
||||||
|
return nil, ArErr{"TypeError", "Expected 1 or 2 argument, got " + fmt.Sprint(len(args)), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "function" {
|
||||||
|
return nil, ArErr{"TypeError", "Expected function, got " + typeof(args[0]), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
var ms int64 = 0
|
||||||
|
if len(args) == 2 {
|
||||||
|
if typeof(args[1]) != "number" {
|
||||||
|
return nil, ArErr{"TypeError", "Expected number, got " + typeof(args[1]), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
if !args[1].(number).IsInt() {
|
||||||
|
return nil, ArErr{"TypeError", "Expected integer, got float", 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
ms = args[1].(number).Num().Int64()
|
||||||
|
}
|
||||||
|
f := js.FuncOf(func(this js.Value, a []js.Value) interface{} {
|
||||||
|
runCall(
|
||||||
|
call{
|
||||||
|
callable: args[0],
|
||||||
|
args: []any{},
|
||||||
|
},
|
||||||
|
stack{},
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
n := js.Global().Call("setInterval", f, ms).Int()
|
||||||
|
IntervalList = append(IntervalList, n)
|
||||||
|
return newNumber().SetInt64(int64(n)), ArErr{}
|
||||||
|
}},
|
||||||
|
"clearTimeout": builtinFunc{"clearTimeout", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return nil, ArErr{"TypeError", "Expected 1 argument, got " + fmt.Sprint(len(args)), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "number" {
|
||||||
|
return nil, ArErr{"TypeError", "Expected number, got " + typeof(args[0]), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
if !args[0].(number).IsInt() {
|
||||||
|
return nil, ArErr{"TypeError", "Expected integer, got float", 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
n := args[0].(number).Num().Int64()
|
||||||
|
for i, v := range TimeoutList {
|
||||||
|
if v == int(n) {
|
||||||
|
TimeoutList = append(TimeoutList[:i], TimeoutList[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
js.Global().Call("clearTimeout", n)
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"clearInterval": builtinFunc{"clearInterval", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return nil, ArErr{"TypeError", "Expected 1 argument, got " + fmt.Sprint(len(args)), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "number" {
|
||||||
|
return nil, ArErr{"TypeError", "Expected number, got " + typeof(args[0]), 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
if !args[0].(number).IsInt() {
|
||||||
|
return nil, ArErr{"TypeError", "Expected integer, got float", 0, "<wasm>", "", true}
|
||||||
|
}
|
||||||
|
n := args[0].(number).Num().Int64()
|
||||||
|
for i, v := range IntervalList {
|
||||||
|
if v == int(n) {
|
||||||
|
IntervalList = append(IntervalList[:i], IntervalList[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
js.Global().Call("clearInterval", n)
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
})
|
||||||
@@ -60,7 +60,7 @@ func parseWhileLoop(code UNPARSEcode, index int, codeline []UNPARSEcode) (whileL
|
|||||||
},
|
},
|
||||||
index+outindex-1,
|
index+outindex-1,
|
||||||
codeline,
|
codeline,
|
||||||
3,
|
2,
|
||||||
)
|
)
|
||||||
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,
|
||||||
3,
|
2,
|
||||||
)
|
)
|
||||||
return whileLoop{
|
return whileLoop{
|
||||||
condition: true,
|
condition: true,
|
||||||
@@ -108,14 +108,13 @@ 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ let interpret(code) = do
|
|||||||
else if (command == '-') do
|
else if (command == '-') do
|
||||||
if (pointer not in memory) memory[pointer] = 0
|
if (pointer not in memory) memory[pointer] = 0
|
||||||
memory[pointer] = memory[pointer] - 1
|
memory[pointer] = memory[pointer] - 1
|
||||||
else if (command == '.') term.log((memory.get(pointer, 0)))
|
else if (command == '.') term.plain.oneLine(chr(memory.get(pointer, 0)), end='')
|
||||||
else if (command == ',') memory[pointer] = ord(input())
|
else if (command == ',') memory[pointer] = ord(input())
|
||||||
else if (command == '[') do
|
else if (command == '[') do
|
||||||
if (memory.get(pointer, 0) == 0) do
|
if (memory.get(pointer, 0) == 0) do
|
||||||
@@ -30,4 +30,5 @@ let interpret(code) = do
|
|||||||
else loops.pop()
|
else loops.pop()
|
||||||
code_ptr = code_ptr + 1
|
code_ptr = code_ptr + 1
|
||||||
|
|
||||||
interpret('>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++.')
|
|
||||||
|
interpret('>++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<++.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-]<+.')
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
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")))
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# 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")
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
import "circular_test"
|
|
||||||
term.log("epic wow")
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
import "circular_import"
|
|
||||||
term.log("hello")
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
import "csv.ar" as csv
|
import "csv" as csv
|
||||||
|
|
||||||
let table = (csv.read("tests/test.csv"))
|
term.log(csv.read("tests/test.csv"))
|
||||||
|
|
||||||
term.log(table)
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
let h = 1e-1000
|
|
||||||
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 x = 100
|
|
||||||
let d = 0
|
|
||||||
|
|
||||||
forever do
|
|
||||||
let n = f(x)
|
|
||||||
term.log("f"+("'"*d)+"("+x+") = "+n)
|
|
||||||
if (n == 0) break
|
|
||||||
f = diff(f)
|
|
||||||
d += 1
|
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
let getInitials(name) = do
|
let getInitials(name) = do
|
||||||
name = name.upper()
|
name = name.upper()
|
||||||
namesplit = name.split(" ")
|
namesplit = name.split(" ")
|
||||||
for (i from 0 to namesplit.length) namesplit[i] = namesplit[i][0]
|
i = 0
|
||||||
|
while (i < namesplit.length) do
|
||||||
|
namesplit[i] = namesplit[i][0]
|
||||||
|
i = i + 1
|
||||||
return namesplit.join("")
|
return namesplit.join("")
|
||||||
|
|
||||||
name = "william bell"
|
name = "william bell"
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
f() = do
|
f() = do
|
||||||
let a = []
|
a = []
|
||||||
for (i from 0 to 1000000) a.append(i)
|
for (i from 0 to 10000) a.append(i)
|
||||||
|
|
||||||
term.log("start")
|
term.log("start")
|
||||||
f()
|
f()
|
||||||
term.log("end")
|
term.log("end")
|
||||||
input()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
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")
|
|
||||||
24
tests/oop.ar
24
tests/oop.ar
@@ -1,24 +0,0 @@
|
|||||||
let toyTank(colour, name) = do
|
|
||||||
let class = {}
|
|
||||||
class.getColour() = do
|
|
||||||
term.log("My colour is", colour)
|
|
||||||
class.getName() = do
|
|
||||||
term.log("My name is", name)
|
|
||||||
class.setColour(newColour) = do
|
|
||||||
colour = newColour
|
|
||||||
class.setName(newName) = do
|
|
||||||
name = newName
|
|
||||||
return class.object()
|
|
||||||
|
|
||||||
|
|
||||||
let tanks = []
|
|
||||||
for (i from 0 to 10) tanks.append(toyTank("red", "tank" + (i+1)))
|
|
||||||
term.log(dir(tanks[0]))
|
|
||||||
for (i from 0 to tanks.length) do
|
|
||||||
tanks[i].getName()
|
|
||||||
tanks[i].getColour()
|
|
||||||
tanks[i].setColour("blue")
|
|
||||||
tanks[i].setName("tank" + (i + 11))
|
|
||||||
tanks[i].getName()
|
|
||||||
tanks[i].getColour()
|
|
||||||
term.log()
|
|
||||||
@@ -1,17 +1,7 @@
|
|||||||
let x = 10
|
x = 10
|
||||||
|
|
||||||
do
|
do
|
||||||
let x = 20
|
let x = 20
|
||||||
term.log(x)
|
term.log(x)
|
||||||
|
|
||||||
term.log(x)
|
term.log(x)
|
||||||
|
|
||||||
term.log()
|
|
||||||
|
|
||||||
let x = 10
|
|
||||||
|
|
||||||
do
|
|
||||||
x = 20
|
|
||||||
term.log(x)
|
|
||||||
|
|
||||||
term.log(x)
|
|
||||||
9
tests/welcomemessage.ar
Normal file
9
tests/welcomemessage.ar
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
term.log(" /\\ |___ \\ ")
|
||||||
|
term.log(" / \\ _ __ __ _ ___ _ __ __ ____) |")
|
||||||
|
term.log(" / /\\ \\ | '__/ _` |/ _ \\| '_ \\ \\ \\ / /__ < ")
|
||||||
|
term.log(" / ____ \\| | | (_| | (_) | | | | \\ V /___) |")
|
||||||
|
term.log(" /_/ \\_\\_| \\__, |\\___/|_| |_| \\_/|____/ ")
|
||||||
|
term.log(" __/ | ")
|
||||||
|
term.log(" |___/ ")
|
||||||
|
term.log("----------------------------------------------")
|
||||||
|
term.log("Welcome to ARGON!")
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user