syntactically homogeneous shell
Find a file
Aidan Hahn c2b86b7f4d Merge branch 'dev' into 'master'
Merge new features to master

See merge request whom/shs!10
2020-08-27 06:51:49 +00:00
ast add a string replace method 2020-08-26 22:32:01 -07:00
cmd fix build from last night 2020-08-21 17:37:54 -07:00
config update debug log usage and add fanciness to log printing 2020-07-23 12:08:29 -07:00
log fixed background process execution 2020-07-23 19:54:36 -07:00
resources/icon incomplete work: big call lib refactor 2020-07-22 00:22:39 -07:00
stdlib added list index function 2020-08-26 23:45:02 -07:00
util handle escaped spaces in tokens + filepaths in completions 2020-08-13 12:14:10 -07:00
.gitignore boolean system 2020-06-28 20:06:55 -07:00
Contributing.md added contribution guide 2019-11-29 13:08:40 -08:00
go.mod change liner source so that we can have good tty config 2020-07-22 23:00:25 -07:00
go.sum change liner source so that we can have good tty config 2020-07-22 23:00:25 -07:00
License.md added contribution guide 2019-11-29 13:08:40 -08:00
Readme.md update readme 2020-07-20 09:42:18 -07:00

shs

Syntactically Homogeneous Shell

Overview

This shell was created to have extremely simple syntax. S-Expressions were chosen to represent statements and the scope of language features were constrained to what could be considered practical for daily shell use. This program is meant to be practical for administrators and daily power users. It can be used for both system administration (as one might use bash or zsh) as well as for the creation of simple programs.

Basic Syntax

When in doubt the print_ast utility can be used to examine the output of the Lex+Parse process. Here you can spot any bugs regarding syntax.

Lists

Any sequence of items within a set of parenthesis is a list (1 "two" three 4)

Lists can be infinitely nested ("one" (2 3 4 (5)))

Data types

We use the following data types

  • Number: 1, 2.0, etc
  • String: "this is a string" (string delimiters: ' " `)
  • Bool: T or F
  • Symbol: a string with no delimiters
  • List: a sequence of elements within parenthesis

Function calls

Any list beginning in a symbol will be considered a function call. From within the shs_repl utility, unknown symbols will be assumed to be system binaries.

(append () 1 2 3) (vim Readme.md) (if (eq "example" (fread 'test_file')) (print "test worked) (rm -rf /))

Variable declaration

There are a few ways to export variables

  • export: (export NAME (value))
  • let: (let ((var1 val1) (var2 val2)) (form_to_be_evaluated))

Currently, let has yet to be implemented

Function declaration

Use the func function from the stdlib: (func name (var1, var2, var3) (form_to_be_evaluated)) In this case, (form_to_be_evaluated) will not be evaluated until the function is called.

Control flow

See stdlib/control_flow.go. We have if, while, and progn forms: (if (cond) (then) (else)) (when (cond) (form1)....... (formN)) (progn (form1)..... (formN)) If and While should be self explanatory. For those new to LISP, the rough idea of progn is to evaluate a sequence of N forms and return the result of the final one. We also have functioning implementations of map and reduce in the stdlib (incomplete)

Comments

The standard delimiter for comments is ; any characters after a semicolon will be ignored until end of line

How to build

Compiling/Installation

  • For now simply run go install cmd/... for each utility you wish to use. If you have GOPATH and GOBIN set it should be usable from PATH

Adding SHS to your application

  • Make sure to set ast.SyncTablesWithOSEnviron, ast.ExecWhenFuncUndef. All of which control integrations with the underlying system.
    • If you do not want the user to be able to set environment variables set ast.SyncTablesWithOSEnviron to false.
    • If you do not want the user to be able to call binaries from the host system, set ast.ExecWhenFuncUndef to false.
  • Get text you are interested in parsing
  • Create a new VarTable and FuncTable (see ast/var_table.go and ast/func_table.go)
  • Call Lex(text) on the text you want to evaluate to recieve a tree of parsed lexemes.
  • Call tree.Eval(FuncTable, VarTable, false) where tree is the returned data from Lex, and the final boolean argument is whether or not to convert unknown symbols to strings. (this is a helpful option if you are writing functions such as those in stdlib/call.go, or any funciton in which you may want to be able to edit and transform the final ast based on your own varaiable table)
  • Make sure the GPLv3 is adhered to
  • OVERRIDE THE STDLIB GenFuncTable FUNCTION. You very likely do NOT want an available function to call system binaries in your embedded shell. Make sure the stdlib Call function is not included.

Configuration

  • variables exported in the repl, if of types string or number, will result in a corresponding variable added to the Environment.
  • one can write arbitrary shs script into .shsrc including function and variable declarations
  • of note are the following variables
    • SH_LOGGING Sets the log level (from 0 to 3)
    • SHS_STATIC_PROMPT Sets the prompt
    • SH_HIST_FILE Sets the history file
    • SH_DEBUG_MODE Adds additional debug output for the lexer (high clutter)
  • additionally, the repl will evaluate any function you define as _SH_PROMPT before the shell prompt
    • if defined, the function will be evaluated before printing the prompt
    • the function will be given 0 arguments
    • if the function does not return a string, its output will be discarded
    • afterwards, the repl will print the values in SHS_STATIC_PROMPT Here is an example of a shs configuration file:
(export GOPATH (concat HOME     "/go"))
(export GOBIN  (concat GOPATH  "/bin"))
(export PATH   (concat PATH ":" GOBIN))
(export GIT_TERMINAL_PROMPT 1)
(export SH_HIST_FILE (concat HOME "/.shs_hist"))
(export SH_LOGGING 0)
(export SHS_STATIC_PROMPT ">")
(func _SH_PROMPT () (concat (?) ($ basename ($ pwd)) "\n"))

The Docs

Contributing

  • Any contribution to this software is welcome as long as it adheres to the conduct guidelines specified in the Contributing.md file in this repository.

License

Copyright (C) 2019 Aidan Hahn.

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/.