All Projects → niieani → bashscript

niieani / bashscript

Licence: MIT license
TypeScript to bash transpiler. Because.

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to bashscript

dotlin
Kotlin to Dart compiler
Stars: ✭ 212 (+472.97%)
Mutual labels:  transpiler
phptojs
PHP-to-JavaScript transpiler
Stars: ✭ 29 (-21.62%)
Mutual labels:  transpiler
Py2Jl.jl
Python to Julia transpiler.
Stars: ✭ 67 (+81.08%)
Mutual labels:  transpiler
dragon
Dragon is a universal Python translater.
Stars: ✭ 26 (-29.73%)
Mutual labels:  transpiler
yahdl
A programming language for FPGAs.
Stars: ✭ 20 (-45.95%)
Mutual labels:  transpiler
CFortranTranslator
A translator from Fortran to C++. We provide statement-wise translation to improve readability.
Stars: ✭ 81 (+118.92%)
Mutual labels:  transpiler
sherlock.py
Sherlock is transpiler that translate python to shell script language.
Stars: ✭ 65 (+75.68%)
Mutual labels:  transpiler
Craxe
Haxe to nim transpiler
Stars: ✭ 39 (+5.41%)
Mutual labels:  transpiler
webfx
A JavaFX application transpiler. Write your Web Application in JavaFX and WebFX will transpile it in pure JS.
Stars: ✭ 210 (+467.57%)
Mutual labels:  transpiler
cotowali
A statically typed scripting language that transpile into POSIX sh
Stars: ✭ 551 (+1389.19%)
Mutual labels:  transpiler
cxgo
Tool for transpiling C to Go.
Stars: ✭ 234 (+532.43%)
Mutual labels:  transpiler
jazzle
An Innovative, Fast Transpiler for ECMAScript 2015 and later
Stars: ✭ 65 (+75.68%)
Mutual labels:  transpiler
Gloa
Glóa - a statically typed language that compiles to Lua. *UNDER DEVELOPMENT*
Stars: ✭ 19 (-48.65%)
Mutual labels:  transpiler
sbt-babel
An SBT plugin to perform Babel compilation.
Stars: ✭ 12 (-67.57%)
Mutual labels:  transpiler
kithon
Python to any languages transpiler
Stars: ✭ 33 (-10.81%)
Mutual labels:  transpiler
elephize
Typescript to PHP translation tool
Stars: ✭ 27 (-27.03%)
Mutual labels:  transpiler
bfpile
Optimizing Brainfuck compiler, transpiler and interpreter
Stars: ✭ 19 (-48.65%)
Mutual labels:  transpiler
sidef
A modern object-oriented programming language implemented in Perl.
Stars: ✭ 109 (+194.59%)
Mutual labels:  transpiler
foolang
A toy programming language.
Stars: ✭ 33 (-10.81%)
Mutual labels:  transpiler
transpiler
ABAP to JS transpiler
Stars: ✭ 57 (+54.05%)
Mutual labels:  transpiler

BashScript

A JavaScript/TypeScript to bash transpiler. Work in progress.

Why? Mainly because I wanted to learn how to make a transpiler.

I also wanted to experiment with bash and how far we could stretch this old, yet widely cross-platform language.

I've previously created a framework trying to make bash as usable as possible: Bash Infinity. This seemed like the natural next step.

Also, because... why not? 🤓

REPL

Not much works, but it's cool. :-)

Find it here: REPL.

Specification (WIP)

Function invocation

Function calls are transpilled as calls to bash functions/commands e.g.

input

echo('hi')

output

echo hi

if the call is used in the position of parameter or assignment: e.g.

input

const out = concat('hi', 'ho')

output

declare out=$(concat 'hi' 'ho')

Function declaration

input

function concat(a, b) {
  return `${a}${b}`
}

output

function concat {
  local a="${1}"
  local b="${2}"
  echo "${a}${b}"
}

Invoking properties

input

const a = 'abc'
const b = a.toLowercase()

output

declare a='abc'
declare b="$(__callProperty a toLowercase)"

Invoking properties with parameters

input

const arr = ['abc']
arr.push('xyz')

output

declare arr=('abc')
__callProperty arr push 'xyz'

Operators

input

const a = 'abc' + 'xyz'

output

declare a="$(__operator_addition 'abc' 'zyx')"

output helpers

# e.g.
__callProperty() {
  if isArray arr
  then
    if property === 'push'
    then
      arr+=("${arr[@]}")
    fi
  fi
}

Lambda functions

input

const concat = (a) => {
  const c = `${a}-super`
  return (b) => {
    return `${c}${b}`
  }
}
const withOne = concat('one')
const result = withOne('two')

output

function concat {
  # params:
  local a="${1}"
  # function body:
  local c="${a}-super"
  # preapplied function:
  # lambda declaration is:
  # [type, name, scoped_declarations_to_eval]
  local -a declaration=(
    function
    __lambda_concat_1
    "$(declare -p c)"
  )
  echo "$(declare -p declaration)"
}

# all functions are top level
function __lambda_concat_1 {
  # scoped variables:
  eval "${1}"; shift;
  # actual function body:
  local b="${1}"
  echo "${c}${b}"
}

function __callVar {
  # TODO: add check if var is a declaration
  eval "${!1}"; shift;
  if [[ "${declaration[1]}" == "function" ]]
  then
    "${declaration[1]}" "${declaration[2]}" "$@"
  fi
}

declare withOne="$(concat 'one')"
declare result="$(__callVar withOne 'two')"

Lambdas with scoped variables

input

const arr = [1, 2, 3]
const result = arr
  .map(num => num + 1)
  .map(num => num - 1)

output

declare declaration=(1 2 3)
declare arr="$(declare -p declaration)"
unset declaration

__lamda_arr_map_anon_1() {
  # scoped variables (if any):
  eval "${1}"; shift;
  # actual function body:
  local num="${1}"
  echo "$(__operator_addition num 1)"
}
__lamda_arr_map_anon_2() {
  # scoped variables (if any):
  eval "${1}"; shift;
  # actual function body:
  local num="${1}"
  echo "$(__operator_substraction num 1)"
}

declare _result1="$(__callProperty arr map __lamda_arr_map_anon_1)"
declare result="$(__callProperty _result1 map __lamda_arr_map_anon_2)"
unset _result1

Objects and other literals

input

const outerObject = {a: 'boom'}
const outerHello = 'hello from outer space!'
const obj = {
  a: {
    aa: 123,
    bbb: {c: ['inner1', 'inner2', 'inner3']}
  },
  b: 'hello',
  c: outerObject,
  d: outerHello,
}

echo(obj.a.aa)

output

#!/usr/bin/env bash
declare -A outerObject=(
  [__type]=object

  [a]="boom"
)

declare outerHello='hello from outer space!'

declare -a __obj_a_bbb_c=(inner1 inner2 inner3)
declare -A __obj_a_bbb=([ref_c]=__obj_a_bbb_c [__type]=object)
declare -A __obj_a=([aa]=123 [ref_bbb]="__obj_a_bbb" [__type]=object)
declare -A obj=(
  [__type]=object

  [ref_a]="__obj_a"
  [b]="hello"
  [ref_c]="outerObject"
  # we need the TypeScript type to tell whether this is a reference or a plain object
  [d]="${outerHello}"
)

# perhaps instead of using the ref_ prefix, we should use an uncommon prefix in the value
# that way we can reuse it for other reference-related functionality

@objectProperty() {
  local objName="$1"
  local property="$2"
  shift
  shift
  local refName="${objName}[\"ref_${property}\"]"
  local typeName="${objName}[\"__type\"]"
  # we need to check type, because bash will return the value of first property if it doesn't exist on the object 🤦
  if [[ -v "${refName}" && "${!typeName}" == 'object' ]]; then
    local value="${!refName}"
    if [[ "${#}" -gt 0 ]]; then
      @objectProperty "${value}" "$@"
      return
    fi
    echo "__ref:${value}"
  else
    refName="${objName}[${property}]"
    if [[ -v "${refName}" ]]; then
      if [[ "${#}" -gt 0 ]]; then
        echo "Error: Cannot read property '${1}' of a non-object '${property}'."
        return
      fi
      echo "${!refName}"
    else
      echo "Error: Cannot read property '${property}' of '${objName}'."
    fi
  fi
}

@objectProperty obj a aa
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].