Adds file-append

This commit is contained in:
sloum 2023-11-27 21:24:20 -08:00
parent 710134ea37
commit 8906ca9280
4 changed files with 146 additions and 8 deletions

2
go.mod
View File

@ -1,4 +1,4 @@
module git.rawtext.club/sloum/felise
module tildegit.org/sloum/felise
go 1.20

View File

@ -113,7 +113,7 @@ func isKeyword(s string) bool {
"type", "while", "dowhile", "if", "else", "and", "or",
">", "<", "=", "stackdump", "clearstack", "->", "<-",
"=>", "->!", "=>!", "append", "append!", "list-get", "list-set",
"list-set!", "split", "join", "file-write", "file-remove",
"list-set!", "split", "join", "file-write", "file-append", "file-remove",
"file-exists?", "file-read", "docstring!", "input", "re-match?",
"re-find", "re-replace", "slice", "stackdepth", "net-get", "try",
"catch", "throw", "import", "rot", "each!", "filter!":

View File

@ -103,13 +103,13 @@ func callKeyword(kw token, r *tokenReader, en *env) error {
case "list-set", "->":
return libSetListItem(kw.line, kw.file)
case "file-append":
return libFileAppend(kw.line, kw.file)
return libFileAppend(kw.line, kw.file, true)
case "file-exists?":
return libFileExists(kw.line, kw.file)
case "file-read":
return libFileRead(kw.line, kw.file)
case "file-write":
return libFileAppend(kw.line, kw.file)
return libFileAppend(kw.line, kw.file, false)
case "docstring!":
return libDocstring(kw.line, r, en, kw.file)
case "input":
@ -1018,7 +1018,7 @@ func libFileRemove(line int, fp string) error {
return nil
}
func libFileAppend(line int, fp string) error {
func libFileAppend(line int, fp string, doAppend bool) error {
p, err := globalStack.Pop()
if err != nil {
return err
@ -1033,13 +1033,21 @@ func libFileAppend(line int, fp string) error {
path := ExpandedAbsFilepath(p.val.(string))
s := toString(data, false)
f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
var caller string
var f *os.File
if doAppend {
f, err = os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
caller = "file-append"
} else {
f, err = os.OpenFile(path, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0644)
caller = "file-write"
}
if err != nil {
return fmt.Errorf("`file-append` could not open or create the path: %s", path)
return fmt.Errorf("`%s` could not open or create the path: %s", caller, path)
}
defer f.Close()
if err != nil {
return fmt.Errorf("`file-append` opened but could not write to the path: %s", path)
return fmt.Errorf("`%s` opened but could not write to the path: %s", caller, path)
}
_, err = f.WriteString(s)
return nil

130
walkthrough.html Normal file
View File

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Felise - A walkthrough</title>
<style>
pre {padding:1rem;width:calc(100% - 2rem);color:#EEE;border-radius:10px;background:#111}
samp > pre{color:lime}
pre .com{color:#88F}
pre{font-weight:bold}
pre .com{font-weight:normal}
</style>
</head>
<body>
<header><nav>Stuff</nav></header>
<main>
<h1>Felise, a concatenative programming language</h1>
<p>This is a walkthrough of the <i>Felise</i> programming language. <i>Felise</i> is loosely situated as a concatenative programming language. It is an interpreted language (it requires the <i>felise</i> interpreter on the system to run programs) in its present form.</p>
<p>This walkthrough will be done by example. You can use the menu to the left to choose a topic, or go sequentially. If you would like to follow along in the <abbr title="Read Evaluate Print Loop">repl</abbr>, you can clone the repository <a href="https://tildegit.org/sloum/felise" target="_blank">here</a>. With that said, let's get to it&hellip;</p>
<section>
<pre><code><span class="com"># This is a comment
| This is also a comment, but it is
used for docstrings (procedure
documentation). It is multiline. |</span>
<span class="com"># Add/View values to/on the stack
# ===============================</span>
5 1.3 "Hello"
stackdump <span class="com"># Take a look at the stack</span>
drop <span class="com"># Throw away TOS ("Hello")</span>
println <span class="com"># Pop and print TOS w/ a newline</span>
print <span class="com"># Pop and print TOS w/ no newline</span>
stackdepth println <span class="com">#=&gt; 0</span>
<span class="com"># Let's do some "math"
# ====================</span>
2 3 + println <span class="com">#=&gt; 5</span>
2 3.2 + println <span class="com">#=&gt; 5.2; INT coerces to FLOAT</span>
2.25 3.1 + println <span class="com">#=&gt; 5.35</span>
"Hello" "World" + println <span class="com">#=&gt; HelloWorld</span>
"Hello" 55 + println <span class="com">#=&gt; Hello55</span>
2 3 - println <span class="com">#=&gt; -1</span>
2.25 3.1 - println <span class="com">#=&gt; -0.8500000000000001</span>
"Hello World" "o" - println <span class="com">#=&gt; HellWrld</span>
"H3ll0 W0rld" 0 - println <span class="com">#=&gt; H3ll Wrld</span>
[ "Hi" "Hello" "Hi" ] "Hi" - println <span class="com">#=&gt; [ "Hello" ]</span>
[ 1 2.25 "Hi" ] 2.25 - println <span class="com">#=&gt; [ 1 "Hi" ]</span>
2 3 / println <span class="com">#=&gt; 0</span>
2.25 3.1 / println <span class="com">#=&gt; 0.7258064516129032</span>
"Hello World" " " / println <span class="com">#=&gt; [ "Hello" "World" ]</span>
2 3 * println <span class="com">#=&gt; 6</span>
2.25 3.1 * println <span class="com">#=&gt; 6.9750000000000005</span>
"Hello World" 2 * println <span class="com">#=&gt; Hello WorldHello World</span>
[ "Hello" "World" ] "__" * println <span class="com">#=&gt; "Hello__World"</span>
<span class="com"># Let's work with variables
# =========================
# Declare the type then the keyword
# then the variable name</span>
INT var! myInt
myInt println <span class="com">#=&gt; 0
# The new var takes on the "zero" value of the type
# using 'myVar' above adds the value of myVar to TOS
# Set the variable as follows:</span>
5 set! myInt
myInt println <span class="com">#=&gt; 5
# You cannot set a variable to a value of a type that
# does not match the declared type:</span>
"Nope" set! myInt <span class="com">#=&gt; ERROR!!!!!</span>
clearstack <span class="com">#=&gt; Clears the stack</span>
<span class="com"># Let's work boolean logic
# ========================</span>
5 3 &gt; println <span class="com">#=&gt; true</span>
5 3 &lt; println <span class="com">#=&gt; false</span>
5 3 &gt;= println <span class="com">#=&gt; true</span>
5 3 &lt;= println <span class="com">#=&gt; false</span>
5 3 = println <span class="com">#=&gt; false</span>
5 3 != println <span class="com">#=&gt; true</span>
5 3 = not println <span class="com">#=&gt; true</span>
true false and <span class="com">#=&gt; false</span>
true false or <span class="com">#=&gt; true</span>
5 type FLOAT = <span class="com">#=&gt; false</span>
5 type INT = <span class="com">#=&gt; false</span>
5 3 &gt; if
"Bigger" println
else
"Smaller" println
end <span class="com">#=&gt; Bigger</span>
<span class="com"># Let's cast some values
# ======================</span>
5 FLOAT cast println <span class="com">#=&gt; Our INT (5) is now a FLOAT (5.0)</span>
"5" FLOAT cast println <span class="com">#=&gt; Our STRING ("5") is now a FLOAT (5.0)</span>
"5" FLOAT cast println <span class="com">#=&gt; Our STRING ("5") is now an INT (5)</span>
"5" BOOL cast println <span class="com">#=&gt; Our STRING ("5") is now a BOOL (true)</span>
"" BOOL cast println <span class="com">#=&gt; Our STRING ("") is now a BOOL (false)</span>
0 BOOL cast println <span class="com">#=&gt; Our INT (0) is now a FLOAT (false)</span>
5 STRING cast println <span class="com">#=&gt; Our INT (5) is now a STRING ("5")</span>
</code></pre>
</section>
</main>
</body>
</html>