Better error handling, early return from procs working better - though needs more testing
This commit is contained in:
parent
547bb46295
commit
c96e2fc0d9
|
@ -0,0 +1,257 @@
|
|||
|
||||
Floodgap Free Software License
|
||||
|
||||
The author of your software has chosen to distribute it under the
|
||||
Floodgap Free Software License. Although this software is without cost,
|
||||
it is not released under Copyleft or GPL, and there are differences
|
||||
which you should read. Your use of this software package constitutes
|
||||
your binding acceptance without restriction.
|
||||
|
||||
This software is without cost
|
||||
|
||||
The Floodgap Free Software License (FFSL) has one overriding mandate:
|
||||
that software using it, or derivative works based on software that uses
|
||||
it, must be free. By free we mean simply "free as in beer" -- you may
|
||||
put your work into open or closed source packages as you see fit,
|
||||
whether or not you choose to release your changes or updates publicly,
|
||||
but you must not ask any fee for it. (There are certain exceptions for
|
||||
for-profit use which we will discuss below.)
|
||||
|
||||
Definitions and terms
|
||||
|
||||
Author
|
||||
The declared copyright owner of this software package.
|
||||
|
||||
Binary
|
||||
A pre-compiled or pre-interpreted bytecode or machine language
|
||||
representation of a software package not designed for further
|
||||
modification and tied to a particular platform or architecture.
|
||||
|
||||
Derivative work
|
||||
Any distribution (q.v.) that contains any modification to or
|
||||
deviation from the official reference distribution (q.v.); or
|
||||
any software package significantly based on or integrally
|
||||
including the source code for its features, including but not
|
||||
limited to supersets; subsets of a significant proportion;
|
||||
in-place patched changes to source or binary files; linking in
|
||||
as a library; binary-only distributions if the original package
|
||||
included source (even if the source was not modified prior to
|
||||
compilation); or translations to another programming language,
|
||||
architecture or operating system environment. Derivative works
|
||||
of packages released under this license are also considered
|
||||
subject to this license.
|
||||
|
||||
However, a software package that requires this package but does
|
||||
not include it or is not based upon it, even if it will not
|
||||
operate without it, is not considered a derivative work. For
|
||||
example, interpreted programs requiring an interpreter issued
|
||||
under this license, assuming they are not distributed with any
|
||||
portion of the interpreter, are not derivative works.
|
||||
|
||||
Distribution
|
||||
A packaged release of this software, either the author's
|
||||
original work (the "reference distribution") or a derivative
|
||||
work based upon it.
|
||||
|
||||
Reference distribution
|
||||
A packaged release of this software explicitly designated as the
|
||||
official release, written by or on behalf of the Author with his
|
||||
or her explicit designation as official. Only exact copies of
|
||||
the reference distribution may be called reference
|
||||
distributions; all other forms are derivative works.
|
||||
|
||||
Source code
|
||||
The human-readable programming instructions of the package which
|
||||
might be easily read as text and subsequently edited, but
|
||||
requiring compilation or interpretation into binary before being
|
||||
directly useable.
|
||||
|
||||
What you are permitted to do under this license
|
||||
|
||||
Pursuant to the remainder of the terms below,
|
||||
* You may freely use, copy, and disseminate this software package for
|
||||
any non-commercial purpose as well as the commercial purposes
|
||||
permitted below.
|
||||
* You may freely modify this package, including source code if
|
||||
available. Your modifications need not be released, although you
|
||||
are encouraged to do so.
|
||||
* You may release your derivative works based upon this software in
|
||||
purely binary (non-source) form if you choose. You are not
|
||||
obligated to release any portion of your source code openly,
|
||||
although you are encouraged to do so.
|
||||
* If this package is a tool used for generation, compilation or
|
||||
maintenance of works, including but not limited to readable
|
||||
documents, software packages or images (for example, compilers,
|
||||
interpreters, translators, linkers, editors, assemblers or
|
||||
typesetters), you may freely use it for that purpose, commercial or
|
||||
otherwise, as the works made by this package are not considered
|
||||
subject to this license unless specified otherwise within and may
|
||||
be distributed under any desired license and/or offered for sale or
|
||||
rental. Any run-time library or run-time code section linked into
|
||||
the output by a compiler or similar code-generating tool governed
|
||||
by this license is considered to be an integral part of the output,
|
||||
and its presence does not subject the generated work to this
|
||||
license either. (This is, of course, assuming you are not using
|
||||
said tools to generate a derivative work based on this package in
|
||||
violation of the other license terms.)
|
||||
However, if you are linking or including a separately distributed
|
||||
library that is under this license, no matter what tool you are
|
||||
using to do the linking or inclusion, you are then considered to be
|
||||
making a derivative work based on that library and your work does
|
||||
fall under this license. To avoid this, do not include the library
|
||||
with your work (even though it needs the library to function) and
|
||||
instead offer the library separately without cost.
|
||||
* In addition to non-commercial use and the uses permitted above, you
|
||||
may use this software package in any for-profit endeavour as long
|
||||
as it does not involve the specific sale or rental of this package.
|
||||
Some specific but by no means exhaustive examples are listed below.
|
||||
Note that some of these situations may require additional action be
|
||||
taken to ensure compliance.
|
||||
+ If this package or a derivative work allows you to serve data
|
||||
or make data available to others (for example, web servers,
|
||||
mail servers, gopher servers, etc.), you may use it to serve
|
||||
any commercial content or in any commercial setting whether
|
||||
you choose to charge a fee or not, as you are considered to be
|
||||
earning income from the content you serve and/or the services
|
||||
facilitated by your business and not from the sale of this
|
||||
package itself. (This is, of course, assuming that you are not
|
||||
charging a fee for sale or rental of this package or a
|
||||
derivative work based on this package in violation of the
|
||||
other license terms.) Similarly, any data you may acquire from
|
||||
the use of this package is yours, and not governed by this
|
||||
license in any way even if for-profit.
|
||||
+ If you are selling a product that includes this package or a
|
||||
derivative work either as part of your product's requirements
|
||||
for function or as a bundled extra, such as an operating
|
||||
system distribution, you may charge a fee for your product as
|
||||
long as you also make this package or said derivative work
|
||||
available for free separately (such as by download or link
|
||||
back to this package's site), as you are considered to be
|
||||
requesting a fee for your own product and the package is
|
||||
merely included as a convenience to your users.
|
||||
+ If you offer installation of this package or a derivative work
|
||||
as a service, you may charge a fee for the act of installation
|
||||
as long as you also make this package or said derivative work
|
||||
available for free (such as by download or link back to this
|
||||
package's site), as you are considered to be requesting a fee
|
||||
for the act of installation and not for the software you are
|
||||
installing.
|
||||
+ The Author may also grant, in writing, other specified
|
||||
exemptions for your particular commercial purpose that do not
|
||||
contravene the spirit of this license or any license terms
|
||||
this package additionally carries.
|
||||
* In your derivative works based on this package, you may choose to
|
||||
offer warranty support or guarantees of performance. This does not
|
||||
in any way make the original Author legally, financially or in any
|
||||
other respect liable for claims issued under your warranty or
|
||||
guarantee, and you are solely responsible for the fulfillment of
|
||||
your terms even if the Author of the work you have based your work
|
||||
upon offers his or her own.
|
||||
* In your derivative works based on this package, you may further
|
||||
restrict the acceptable uses of your package or situations in which
|
||||
it may be employed as long as you clearly state that your terms
|
||||
apply only to your derivative work and not to the original
|
||||
reference distribution. However, you may not countermand or ignore,
|
||||
directly or otherwise, any restriction already made in the
|
||||
reference distribution's license, including in this document
|
||||
itself, in similar fashion to other licenses allowing compatible
|
||||
licenses to co-govern a particular package's use.
|
||||
|
||||
What you must not do under this license
|
||||
|
||||
Remember that these limits apply only to redistribution of a reference
|
||||
distribution, or to a true derivative work. If your project does not
|
||||
include this package or code based upon it, even if it requires this
|
||||
package to function, it is not considered subject to this license or
|
||||
these restrictions.
|
||||
* You must not charge a fee for purchase or rental of this package or
|
||||
any derivative work based on this package. It is still possible to
|
||||
use this package in a commercial environment, however -- see What
|
||||
you are permitted to do under this license.
|
||||
* You must not countermand or ignore, directly or otherwise, the
|
||||
restrictions already extant in this package's license in your
|
||||
derivative work based on it. As a corollary, you must not place
|
||||
your derivative work under a secondary license or description of
|
||||
terms that conflicts with it (for example, this license is not
|
||||
compatible with the GNU Public License).
|
||||
* You must not label any modified distribution of this package as a
|
||||
reference or otherwise official distribution without the permission
|
||||
of the original Author or Authors. You must clearly specify that
|
||||
your modified work is a derivative work, including binary-only
|
||||
releases if the original included source code and you do not even
|
||||
if you did not modify the source prior to compilation.
|
||||
|
||||
What you must do under this license
|
||||
|
||||
* You must agree to all terms specified (agreement to which is
|
||||
unconditionally signified by your usage, modification or
|
||||
repurposing of this package), or to remove the package from your
|
||||
computer and not use it further.
|
||||
* In the absence of any specific offer for redress or assistance
|
||||
under warranty or guarantee of performance that the Author of this
|
||||
package might make, you must agree to accept any and all liability
|
||||
that may come from the use of this package, proper or improper,
|
||||
real or imagined, and certify without condition that you use this
|
||||
product at your own risk with no guarantee of function,
|
||||
merchantability or fitness for a particular purpose. If such offer
|
||||
of redress or assistance is extended, it is fulfillable only by the
|
||||
Author who extended the offer, which might not necessarily be this
|
||||
Author, nor might it be the Authors of any packages it might be
|
||||
based upon.
|
||||
* If you choose to publicly redistribute this package or create a
|
||||
derivative work based on this package, you must make it available
|
||||
without any purchase or rental fee of any kind.
|
||||
* If you choose to create a derivative work based on this package,
|
||||
your derivative work must be copyrighted, and must be governed
|
||||
under (at a minimum) the original package's license, which will
|
||||
necessarily include all terms noted here. As such, if you choose to
|
||||
distribute your derivative work, you must include a human-readable
|
||||
license in your distribution containing all restrictions of use,
|
||||
necessarily including this license, and any additional restrictions
|
||||
the Author has mandated that do not contravene this license which
|
||||
you and users of your derivative work must also honour.
|
||||
* If you choose to create and distribute a derivative work based on
|
||||
this package, your derivative work must clearly make reference to
|
||||
this package, any other packages your work or the original work
|
||||
might be based on, and all applicable copyrights, either in your
|
||||
documentation, your work's standard human-readable output, or both.
|
||||
A suggested method might be
|
||||
|
||||
Contains or is based on the Foo software package.
|
||||
Copyright (C) 2112 D. Original Author. All rights reserved.
|
||||
http://their.web.site.invalid/
|
||||
|
||||
Additional notes
|
||||
|
||||
Enforcement is the responsibility of the Author. However, violation of
|
||||
this license may subject you to criminal and civil penalties depending
|
||||
on your country.
|
||||
|
||||
This package is bound by the version of license that accompanies it.
|
||||
Future official versions of a particular package may use a more updated
|
||||
license, and you should always review the license before use. This
|
||||
license's most current version is always available from the following
|
||||
locations:
|
||||
|
||||
[1]http://www.floodgap.com/software/ffsl/
|
||||
[2]gopher://gopher.floodgap.com/1/ffsl/
|
||||
|
||||
This license is version 1, dated 19 November 2006.
|
||||
|
||||
This license is copyright © 2006 Cameron Kaiser. All rights reserved.
|
||||
The text of this license is available for re-use and re-distribution
|
||||
under the Creative Commons. The use of the term "Floodgap Free Software
|
||||
License" does not imply endorsement of packages using this license by
|
||||
Floodgap Systems or by Cameron Kaiser. Modified licenses using portions
|
||||
of these terms may refer to themselves as modified FFSL, with the
|
||||
proviso that their modifications be clearly marked in accordance with
|
||||
the Creative Commons Attribution-ShareAlike 2.5 License.
|
||||
|
||||
Only the text of this license, and not programs covered by this
|
||||
license, is so offered under Creative Commons.
|
||||
|
||||
References
|
||||
|
||||
1. http://www.floodgap.com/software/ffsl/
|
||||
2. gopher://gopher.floodgap.com/1/ffsl/
|
||||
|
42
README.md
42
README.md
|
@ -2,5 +2,45 @@
|
|||
|
||||
_felise_ is a [concatenative](https://en.wikipedia.org/wiki/Concatenative_programming_language) programming language. It is a hobby language designed as a successor to [nimf](https://git.rawtext.club/nimf-lang/nimf) (an earlier programming language by the same author). The language is implemented as a basic AST walking interpreter interpreter (though a compiler, JIT, or bytecode/vm would also be possible) in [golang](https://golang.org). It is not dynamically typed and all variables need to be declared as a given type (even control structures like `if` and `while` are technically types as well). Type checks are generally handled at runtime, with a few handling in the lex/parse phases.
|
||||
|
||||
More details coming when I have time to finish writing this.
|
||||
## Example
|
||||
|
||||
``` forth
|
||||
proc fib
|
||||
| calculates the nth fibonacci number
|
||||
where n is an INT on TOS at call time |
|
||||
|
||||
INT var fib#
|
||||
set fib#
|
||||
|
||||
fib# 0 = if 1 .
|
||||
|
||||
fib# 1 = if 3 .
|
||||
|
||||
fib# 1 > if
|
||||
INT var grandparent 1 set grandparent
|
||||
INT var parent 3 set parent
|
||||
INT var i 2 set i
|
||||
INT var me
|
||||
|
||||
proc continue-loop?
|
||||
i fib# < i
|
||||
.
|
||||
|
||||
<=fib#
|
||||
while
|
||||
3 parent *
|
||||
grandparent -
|
||||
set me
|
||||
parent set grandparent
|
||||
me set parent
|
||||
i 1 + set i
|
||||
<=fib#
|
||||
.
|
||||
me
|
||||
.
|
||||
.
|
||||
|
||||
5 fib println
|
||||
```
|
||||
|
||||
|
||||
|
|
12
env.go
12
env.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
16
globals.go
16
globals.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
|
@ -24,4 +36,8 @@ const (
|
|||
|
||||
var (
|
||||
debug bool = false
|
||||
|
||||
// This is the main stack for the language
|
||||
globalStack stack = NewStack()
|
||||
globalRetStack stack = NewStack()
|
||||
)
|
||||
|
|
16
helpers.go
16
helpers.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
@ -111,10 +123,10 @@ func isKeyword(s string) bool {
|
|||
<- add value from array to TOS
|
||||
*/
|
||||
switch s {
|
||||
case "var", "set", "+", "-", "*", "/",
|
||||
case "var", "set", "+", "-", "*", "/", "proc",
|
||||
"length", "ref", "return", "print", "println", "dup",
|
||||
"drop", "over", "swap", "cast", "type", "while", "dowhile",
|
||||
"if", "else", "&&", "||", ">", "<", "=", "stackdump",
|
||||
"if", "else", "and", "or", ">", "<", "=", "stackdump",
|
||||
"clearstack":
|
||||
return true
|
||||
default:
|
||||
|
|
28
interpret.go
28
interpret.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
@ -5,12 +17,13 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// This is the main stack for the language
|
||||
var globalStack stack = NewStack()
|
||||
|
||||
func interpret(tokens []token, en *env) error {
|
||||
r := NewTokenReader(tokens)
|
||||
for t, err := r.Read(); err == nil; t, err = r.Read() {
|
||||
if globalRetStack.Depth() > 0 {
|
||||
return nil
|
||||
}
|
||||
ReplacedSymbol:
|
||||
switch t.kind {
|
||||
case FLOAT, INT, STRING, BOOL, TYPE:
|
||||
|
@ -83,13 +96,18 @@ ReplacedSymbol:
|
|||
return fmt.Errorf("ERROR │ Line %d\n │ Could not find symbol `%s`\n", t.line, t.val.(string))
|
||||
}
|
||||
t = foundIn.vars[t.val.(string)]
|
||||
|
||||
// Run a procedure
|
||||
if t.kind == PROC {
|
||||
err = interpret(t.val.(proc).body, NewEnv(en))
|
||||
if err != nil {
|
||||
// This join is meant to create a callstack trace of sorts
|
||||
// so that if an error was found multiple procs deep each
|
||||
// _should_ adds it proc name and line to the list.
|
||||
return errors.Join(err, fmt.Errorf(" ├ In procedure `%s` on line %d", t.val.(proc).name, t.line))
|
||||
return errors.Join(err, fmt.Errorf(" - In procedure `%s` on line %d", t.val.(proc).name, t.line))
|
||||
}
|
||||
if globalRetStack.Depth() > 0 {
|
||||
globalRetStack.Pop()
|
||||
}
|
||||
} else {
|
||||
goto ReplacedSymbol
|
||||
|
@ -97,6 +115,10 @@ ReplacedSymbol:
|
|||
case KEYWORD:
|
||||
// Handle early exit from a proc
|
||||
if (t.val.(string) == "return" && en.parent != nil) || t.val.(string) == "break" {
|
||||
err := globalRetStack.Push(t)
|
||||
if err != nil {
|
||||
return fmt.Errorf(stackErrFmt, line, err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := callKeyword(t, r, en)
|
||||
|
|
72
keywords.go
72
keywords.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
@ -7,6 +19,13 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
TODO / Notes on broken things
|
||||
|
||||
- Add `not`
|
||||
|
||||
*/
|
||||
|
||||
func callKeyword(kw token, r *tokenReader, en *env) error {
|
||||
switch kw.val.(string) {
|
||||
case "+":
|
||||
|
@ -22,22 +41,22 @@ func callKeyword(kw token, r *tokenReader, en *env) error {
|
|||
case "set":
|
||||
return libSet(kw.line, r, en)
|
||||
case "print":
|
||||
return libPrint(false)
|
||||
return libPrint(false, kw.line)
|
||||
case "println":
|
||||
return libPrint(true)
|
||||
return libPrint(true, kw.line)
|
||||
case "dup":
|
||||
return libDuplicate()
|
||||
return libDuplicate(kw.line)
|
||||
case "swap":
|
||||
return libSwap()
|
||||
return libSwap(kw.line)
|
||||
case "over":
|
||||
return libOver()
|
||||
return libOver(kw.line)
|
||||
case "drop":
|
||||
return libDrop(kw.line)
|
||||
case "cast":
|
||||
return libConvertType(kw.line)
|
||||
case "&&":
|
||||
case "and":
|
||||
return libLogicalAnd(kw.line)
|
||||
case "||":
|
||||
case "or":
|
||||
return libLogicalOr(kw.line)
|
||||
case "=":
|
||||
return libEqual(kw.line)
|
||||
|
@ -193,7 +212,7 @@ func libSet(line int, r *tokenReader, en *env) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func libPrint(newline bool) error {
|
||||
func libPrint(newline bool, line int) error {
|
||||
v1, err := globalStack.Pop()
|
||||
if err != nil {
|
||||
return fmt.Errorf(stackErrFmt, line, err.Error())
|
||||
|
@ -206,12 +225,15 @@ func libPrint(newline bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func libDuplicate() error {
|
||||
globalStack.Push(globalStack.Peek())
|
||||
func libDuplicate(line int) error {
|
||||
err := globalStack.Push(globalStack.Peek())
|
||||
if err != nil {
|
||||
return fmt.Errorf(stackErrFmt, line, err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func libSwap() error {
|
||||
func libSwap(line int) error {
|
||||
v2, err := globalStack.Pop()
|
||||
if err != nil {
|
||||
return fmt.Errorf(stackErrFmt, line, err.Error())
|
||||
|
@ -225,7 +247,7 @@ func libSwap() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func libOver() error {
|
||||
func libOver(line int) error {
|
||||
v2, err := globalStack.Pop()
|
||||
if err != nil {
|
||||
return fmt.Errorf(stackErrFmt, line, err.Error())
|
||||
|
@ -311,21 +333,24 @@ func libGreaterThan(line int) error {
|
|||
if v1.kind == v2.kind {
|
||||
switch v1.kind {
|
||||
case STRING:
|
||||
globalStack.Push(token{BOOL, v1.val.(string) > v1.val.(string), line})
|
||||
err = globalStack.Push(token{BOOL, v1.val.(string) > v2.val.(string), line})
|
||||
case INT:
|
||||
globalStack.Push(token{BOOL, v1.val.(int) > v1.val.(int), line})
|
||||
err = globalStack.Push(token{BOOL, v1.val.(int) > v2.val.(int), line})
|
||||
case FLOAT:
|
||||
globalStack.Push(token{BOOL, v1.val.(float64) > v1.val.(float64), line})
|
||||
err = globalStack.Push(token{BOOL, v1.val.(float64) > v2.val.(float64), line})
|
||||
default:
|
||||
return fmt.Errorf("ERROR | Line %d\n %s is not a comparable type\n", line, kindToString(v1.kind))
|
||||
}
|
||||
} else if (v1.kind == INT && v2.kind == FLOAT) {
|
||||
globalStack.Push(token{BOOL, float64(v1.val.(int)) > v1.val.(float64), line})
|
||||
err = globalStack.Push(token{BOOL, float64(v1.val.(int)) > v2.val.(float64), line})
|
||||
} else if (v1.kind == FLOAT && v2.kind == INT) {
|
||||
globalStack.Push(token{BOOL, v1.val.(float64) > float64(v1.val.(int)), line})
|
||||
err = globalStack.Push(token{BOOL, v1.val.(float64) > float64(v2.val.(int)), line})
|
||||
} else {
|
||||
return fmt.Errorf("ERROR | Line %d\n %s and %s cannot be compared\n", line, kindToString(v1.kind), kindToString(v2.kind))
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf(stackErrFmt, line, err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -341,21 +366,24 @@ func libLessThan(line int) error {
|
|||
if v1.kind == v2.kind {
|
||||
switch v1.kind {
|
||||
case STRING:
|
||||
globalStack.Push(token{BOOL, v1.val.(string) < v1.val.(string), line})
|
||||
err = globalStack.Push(token{BOOL, v1.val.(string) < v2.val.(string), line})
|
||||
case INT:
|
||||
globalStack.Push(token{BOOL, v1.val.(int) < v1.val.(int), line})
|
||||
err = globalStack.Push(token{BOOL, v1.val.(int) < v2.val.(int), line})
|
||||
case FLOAT:
|
||||
globalStack.Push(token{BOOL, v1.val.(float64) < v1.val.(float64), line})
|
||||
err = globalStack.Push(token{BOOL, v1.val.(float64) < v2.val.(float64), line})
|
||||
default:
|
||||
return fmt.Errorf("ERROR | Line %d\n %s is not a comparable type\n", line, kindToString(v1.kind))
|
||||
}
|
||||
} else if (v1.kind == INT && v2.kind == FLOAT) {
|
||||
globalStack.Push(token{BOOL, float64(v1.val.(int)) < v1.val.(float64), line})
|
||||
err = globalStack.Push(token{BOOL, float64(v1.val.(int)) < v2.val.(float64), line})
|
||||
} else if (v1.kind == FLOAT && v2.kind == INT) {
|
||||
globalStack.Push(token{BOOL, v1.val.(float64) < float64(v1.val.(int)), line})
|
||||
err = globalStack.Push(token{BOOL, v1.val.(float64) < float64(v2.val.(int)), line})
|
||||
} else {
|
||||
return fmt.Errorf("ERROR | Line %d\n %s and %s cannot be compared\n", line, kindToString(v1.kind), kindToString(v2.kind))
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf(stackErrFmt, line, err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
12
lexer.go
12
lexer.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
32
main.go
32
main.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
@ -28,12 +40,13 @@ var linerTerm ln.ModeApplier = nil
|
|||
_
|
||||
|, _ |. __ _
|
||||
| (/,||_) (/,
|
||||
|
||||
TODO / Ideas / Etc.
|
||||
|
||||
|
||||
Ideas:
|
||||
|
||||
del [varname/procname]
|
||||
Will remove the symbol and value from the symbol table
|
||||
Will remove the symbol and value from the symbol table,
|
||||
not sure if this is useful but it feels like it adds
|
||||
completeness
|
||||
|
||||
// XXX note sure about these array ops
|
||||
-> [varname]
|
||||
|
@ -47,6 +60,7 @@ length [varname]
|
|||
Will put the length of the var on TOS if is it a string
|
||||
or an array
|
||||
|
||||
// Not yet sure how to do this
|
||||
ref [ident/symbol]
|
||||
Put the symbol on TOS, to reference something that would
|
||||
otherwise be executed immediately (if, while, proc, etc)
|
||||
|
@ -76,7 +90,7 @@ Syntactic sugar:
|
|||
|
||||
Builtins on radar:
|
||||
|
||||
- `+`, `-`, `*`, `/`, `%`
|
||||
- `%`, `not`
|
||||
- `open`
|
||||
- Opens a connection or file and returns a handle
|
||||
- `close`
|
||||
|
@ -87,6 +101,12 @@ Builtins on radar:
|
|||
- Read from the given handle to the stack
|
||||
- `append`
|
||||
- Appends TOS to a string, file, array, or open connection
|
||||
|
||||
Need some way to respond to args given at runtime... may need
|
||||
an array for that. Or maybe not? Maybe an `arg` word can be
|
||||
defined so that: `0 INT arg myarg` would let someone pass an
|
||||
arg: `felise myfile.fe --myarg=24`, with the arg defaulting to
|
||||
0... does something like that work?
|
||||
*/
|
||||
|
||||
func prompt(l *ln.State, cont bool) string {
|
||||
|
@ -161,7 +181,7 @@ func lexParseInterpret(s string, en *env) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO add file input
|
||||
func main() {
|
||||
verFlag := flag.Bool("v", false, "Print version information and exit")
|
||||
flag.BoolVar(&debug, "debug", false, "Turns on debug mode")
|
||||
|
|
12
parser.go
12
parser.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
12
stack.go
12
stack.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
12
types.go
12
types.go
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
|
||||
|
||||
This source code is available under the terms of the ffsl, or,
|
||||
Floodgap Free Software License. A copy of the license has been
|
||||
provided as the file 'LICENSE' in the same folder as this source
|
||||
code file. If for some reason it is not present, you can find the
|
||||
terms of version 1 of the FFSL at the following URL:
|
||||
|
||||
https://www.floodgap.com/software/ffsl/license.html
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
Loading…
Reference in New Issue