GithubHelp home page GithubHelp logo

davafons / eggtended-js Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 1.0 1.81 MB

An extended version of the Egg programming language from the "Eloquent Javascript" book.

License: GNU General Public License v3.0

JavaScript 100.00%

eggtended-js's People

Contributors

davafons avatar dependabot[bot] avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

adriancmiranda

eggtended-js's Issues

Introduce stubbing techniques for testing

Investigate what stubbing is, and how to implement it for mocking parts of the test.
Resources:
Library: Sinon
Code example

 describe("run", function() {
    let originalLog;
    beforeEach(function() {
      originalLog = console.log;
      console.log = function (...args) { 
        ...
      };
    });
    // test code here
    afterEach(function() {
      ...
    });
    it("testing one.egg with mocking of console.log", function() {
      ...
    }
}

Add throw - try-catch-finally blocks to the Egg

Add syntax in Egg to handle throwing and catching errors. Something like:

do(
  try(
    do {  # Try
      throw(42)
    },
    do {  # Catch
      print(+("Caught error! ", __error__))
    }
  ),
  try(
    do {  # Try
      print(20)
    },
    do {  # Catch
      print(+("Caught error! ", __error__))
    },
    do {  # Finally
      print("Finally called")
    }
  )
)

Add a 'sub' method for indexing Maps

Implement the method 'sub' allowing to index maps.
Example:

do(
  def(x, map{a: 1, b: 4, c: map{d: 5, e: 3}}),
  print(x["sub", "a"]),     # 1
  print(x["sub", "c"]),     # Map { d: 5, e: 3 }
  print(x["sub", "c", "e"]) # 3
)

Add the 'dot' operator to Egg

Add the DOT operator as an alternative for the (...) syntax.
Example:

do(
  def(x, array[1,4,5]),
  def(s, x.join("-")),                 # The same as x("join", "-")
  print(s),                            # 1-4-5
  print(array[1,4,5].join("-").length) # 5
)

With Egg objects:

do (
  def(x, object ( 
    c:   0,
    gc:  ->{this.c},
    sc:  ->{value, =(this, "c", value)},
    inc: ->{=(this, "c", +(this.c, 1))}
  )),
  print(x),
  print(x["c"]),
  print(x.c),
  print(x.gc),             # calls the function!
  print(element(x, "gc")), # [Function: bound ]
  print(x("sub", "gc")),   # [Function: bound ]
  print(x.sub("gc")),      # [Function: bound ]
  print(x.sc(5)),
  print(x("sc", 5)),
  print(x.gc)
)

With numbers:

do{
  print(4.toFixed(2)),
  def(x, 4),
  print(x("toFixed", 2)),
  def(z, x.toFixed(2)),
  print(z),
}

Proposal: Add optional typing to the language

Add optional typing to the language, with a syntax and a functionality simillar to:

do(
  define(num(x), 3), # OK
  define(str(y), 5), # This should fail
  define(myfun, fun(int(x), print(x))), # Add type to function parameters
  myfun(4.3)
) 

Some basic types to implement:

  • num
  • str
  • bool
  • ¿User defined types?

Note: Should be nice to merge this structure with the __const__ structure in a __symbol_table__ structure with all the attributes.

Add a 'require' to the language

Expand Egg with a 'require' (like NODE) allowing to use libraries.
Example:

# module. Exports z
do {
  print("inside module"),
  :=(z, map{inc: ->{x, 
                     +(x,1)
                   } # end fun
           } # end map
  ), # end of :=
  z  # el último valor será exportado
}

Add hashes/maps to the Egg language

Add support for defining map in Egg.
Example

do {
  def(x, map["x", 4, "y", map["z", 3]]),
  print(x),                               # { x: 4, y: { z: 3 } }
  print(element(x, "x")),                 # 4
  print(element(x, "y")),                 # { z: 3 }
  print(element(x, "y", "z"))             # 3
}

Add 'True OOP' to the Egg interpreter.

Add objects to the language.
Example;

do (
  def(x, object ( 
    "c", 0,
    "gc", ->{element[this, "c"]},
    "sc", ->{value, =(this, "c", value)},
    "inc", ->{=(this, "c", +(element[this, "c"],1))}
  )),
  print(x),
  print(x("gc")),
  x("sc", 4),
  print(x("gc")),
  x("inc"),
  print(x("gc")),
)

Use the 'y' flag on the regex. Don't destroy the input string (program)

The parsing should be done with strings using the 'y' (sticky) flag. This way its easier to detect errors and avoid skipping tokens accidentally.

As a side effect, the parsing should be done without deleting the tokens from the original string with the program, only searching from lastIndex

Extend 'set' to modify array elements

Extend the operator 'set' to allow modifying the value of an array using its index.
Example

do(
  def(x, array[1,2,3, array[9,8,7]]),
  set(x, 2, 9),
  print(x),             # [ 1, 2, 9, [ 9, 8, 7 ] ]
  set(x, 3, 1, 1000),
  print(x)              # [ 1, 2, 9, [ 9, 1000, 7 ] ]
)

Allow calling 'element' with several indices

Add the posibility to index with several indices.
Example:

do(
  def(x, array[1, array[2,3]]),
  print(element(x,0)),          # 1
  print(element(x,1)),          # [ 2, 3 ]
  print(element(x,1,1)),        # 3
  print(element(x,-1,-1)),      # 3
  print(element(x,-1,0))        # 2
 )

Call the method 'missing' if another method couldn't be called

When calling an undefined method, give the option to call the method 'missing' if defined. If even 'missing' is not defined, throw an exception.

Example (with Monkey Patching for 'missing => +':

do(
  print(4("undefined-method", 2, 3)) # 9. Called 'missing', aliased to '+'
)

Call JS attributes for objects

Related to #9.

Modify the apply node so if a Javascript obj has an attribute called attr, it should be returned.

Example:

do( # test properties in egg
  def(x, array[1,array[3,2,5]]),
  print(x("length")),          # 2
  print(x["sub", 1]("length")) # 3
)

Add inheritance between objects with 'child' method

Add inheritance between objects with child

Example:

do(
  def(x, object ( 
    "c", 0,
    "gc", ->{element[this, "c"]},
    "sc", ->{value, =(this, "c", value)},
    "inc", ->{=(this, "c", +(element[this, "c"],1))}
  )),
  def(y, child(x)),
  print(y.sc(5)),
  print(y.c)
)

Add 'regexps' to Egg

Add support for using regexps with Egg
Example:

do {
  :=(d, r/
         (?<year>  \d{4} ) -?  # year 
         (?<month> \d{2} ) -?  # month 
         (?<day>   \d{2} )     # day
        /x),
  print(d.test("1987-07-14")),  # true
  :=(m, d.exec("1987-07-14")),  
  print(m), #  [ '1987-07-14', '1987', '07', '14', index: 0, input: '1987-07-14' ]
  print(m.index), # 0
    
  :=(x, RegExp.exec("2015-02-22", d)), 
                  /*
                  [ '2015-02-22',
                    '2015',
                    '02',
                    '22',
                    index: 0,
                    input: '2015-02-22',
                    year: '2015',
                    month: '02',
                    day: '22' ]
                  */
  print(x),
  print(x.year), # 2015
  print(x.month) # 02
}

Call JS method for objects

Modify the evaluation of the apply nodes for calling methods.
Example
Given the following program:

obj("meth", args)

If the Javascript object obj has a method named 'meth', it should be called with the arguments args.

Also, these method calls should be able to be concatenated:

print(x("join", "-")("toUpperCase"))

Modify Egg to accept the program in 'examples/reto.egg'

Modify the current version of the Egg language to allow this program as an input:

  do {
    def(sum,  ; function
      -> { nums, 
        do {
           := (i, 0), # Creates a local variable i and sets to 0
           := (s, 0), # Creates local var s and sets to 0
           while { <(i, length(nums)),
             do { =(s, +(s, <-(nums, i))),
                =(i, +(i, 1))
             }
           },
           s
        }
     )
   },
   print(+("sum(array[1, 2, 3]) := ", sum(array[1, 2, 3])))
  }

Modify the 'evaluate' function using an OOP approach

Instead of running a switch statement on the evaluate function, replace it with three classes:

  • Value
  • Word
  • Apply

Each one with a evaluate method.

This classes should be defined on a separated file caled lib/ast.js

Create a test for 'examples/scope-err.egg'

Create a new test that shows how the program in 'examples/scope-err.egg'...

  do( 
    set(x,9),
    print(x) # ReferenceError: Tried setting an undefined variable: x
  )

...Throws an error like ReferenceError: Tried setting an undefined variable: x

PROPOSAL: Make a web version of the REPL

Investigate if making a web version of the REPL loop could be possible, and try to implement it.

If possible, should be implemented on a static website to allow hosting on github pages

Related to #5.

Commmand line processing for Egg

Extend Egg to allow passing arguments from the command line
Example

do {
  use('command-line'),
  :=(optionDefinition, arr [
    map { name: 'verbose', alias: 'v', type: Boolean },
    map { name: 'src', type: String, multiple: true, defaultOption: true },
    map { name: 'timeout', alias: 't', type: Number },
    map { name: 'help', alias: 'h', type: Boolean },
  ]),
  :=(options, parseArgs(optionDefinitions)),
  print(options)
    /* options es un map como este:
        {
          src: [
            'one.js',
            'two.js'
          ],
          verbose: true,
          timeout: 1000
        }
    */
}

Unify 'egg' and 'eggc' binaries on a single CLI tool

Use commander npm package to unify the ./bin/egg and ./bin/eggc binaries into a single CLI tool.

When called without arguments, should call the REPL.
Optional arguments:

  • -r --run: Compile and run a .egg program
  • -c --compile: Compile .egg program, save the resulting tree on a .evm file.
  • -i --interpret: Interpret (run) a .evm.

Create a test for 'examples/one.egg'

Test that the program examples/one.egg...

  do(
    define(x, 4),
    define(setx, fun(val, 
        set(x, val)
      )
    ),
    setx(50),
    print(x)
  )

Returns the expected output, 50

Create the REPL loop for Egg.

Create a REPL interpreter for Egg (Like the Python interpteter, or the Ruby irb)

There is a video on the school resources about how to do do one.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.