Code Monkey home page Code Monkey logo

wtf-interp's Introduction

An interpreted language inspired by Ruby, Elixir, CoffeeScript, Python, etc

Learn from Examples
  • Basic Data Types
  # Integers
  a = 1;
  
  # Strings
  b = "abc";
  
  # Lists
  lst = [1, 2, 5, "hello world"];
  each(lst, -> (item) { puts(item); });
  puts(lst[3]);

  # 2D list
  lst1 = [[1, 3, 5],
          [2, 4, 6],
          [3, 5, 7]];
  puts(to_s(lst1[0][0]));

  # Booleans and Nil
  puts([True, False, Nil]);
  
  # Hash Map
  map = {a: 2 + 3};
  puts(map["a"]);
  
  # Functions
  puts(Type::is_a(1, Type::Int));
  puts(Type::is_a(1, Type::Float));
  puts(Type::is_a(Type::is_a, Type::Function));
  • Operators
  puts(-1);
  puts(1 + 2);
  puts(1 - 2);
  puts(1 * 2);
  puts((3 + 4) * 5);
  puts("abc" == "abc");
  puts("abc" != "abcd");
  puts("abc" != 1);
  puts(Nil == Nil);
  puts(1 > 2);
  puts(1 >= 1);
  • Basic Statements
  puts(
    if (True) {
      "true";
    } else {
      "false";
    }
  );
  • Functions as First Citizens
  fn = ->() { -> () { "fn"; }; };
  fn1 = ->(x, *args) {
    x + args[0] + args[1] + args[2] + 1;
  };
  puts(whats(fn));
  puts(whats(fn()));
  puts(fn()());
  puts(fn1(1, 2, 3, 4));
  
  • Modules
  C = module {
    B = module {
      A = 1;
    };
  };
  puts(C::B::A);
  
  include(C::B);
  puts(A);
  • require() v.s. import()
  # a.wtf
  A = 1
  
  # b.wtf
  B = 2
  
  # "require" is like Ruby's require
  # It defines all vars of the required file in current bindings
  
  # require.wtf
  a = require("./a");
  puts(A); # => 1
  puts(a); # => 1
  
  # "import" is like Python's import
  # It does not affect current bindings,
  #   but returns a module object containing 
  #   all vars defined in the imported file
  
  # import.wtf
  b = import("./b");
  puts(b);      # => <module ./b.wtf>
  puts(b::B);   # => 1
  • Pattern Matching
  let {a: a} = {a: 1};
  let {b: [b, c]} = {b: [2, 3]};
  puts(a);
  puts(b);
  puts(c);
  
  let d = 4;
  let {} = {};
  let [] = [];
  let [{e: e}] = [{e: 5}];
  puts(d);
  puts(e);
  
  let [f, g, _] = [1, 2, 3];
  let [h, i, *j] = [1, 2, 3, 4, 5];
  puts(j);
  
  let k, l, m = [4, 5, 6];
  puts(k);

  let n: {p: p}, o: o = {n: {p: 5}, o: 8};
  puts(p);
  
  # case-when statments supports pattern matching
  fn = ->(a) {
    case (a) {
      when (1) {
        "a";
      }
      when ({x: x}) {
        x;
      }
      else {
        Nil;
      }
    };
};

puts(fn(1));
puts(fn({x: "x"}));
puts(fn("abc"));
  • Exceptions
  secure {
    let [a, b, c, d] = [1, 2, 3];
  } rescue {type: type, message: message} {
    puts("rescue");
    puts(to_s(type));
  };
  • Misc
  # "eval" is not so "evil"
  puts(eval("-> { puts(2+3); }")());
  
  # Command Line Arguements
  puts(ARGV);

TODOs

  • syntax

    • regex
    • map pattern matching on fn_def
    • if no-else, if elsif else
  • stdlib

    • math
    • io
    • promise

Language Design

  1. Main Goals
    1. Make the programmers happy.
    2. Functional.
    3. What-you-see-is-what-you-get syntax.
    4. Simple basic syntax plus syntax sugars.
    5. Code fast, cod short.
    6. Do not refactor, rewrite it.
    7. Ruby inter-ops.
    8. Threads are shit.

Design Details

  • wtf.rb

    • Interpret executable
  • lexer.rb

    • Lexer
  • parse.y

    • yacc-like parser
  • eval.rb

    • Implement "eval"-like functions in Ruby
    • e.g. eval(str), require(file), import(file)
  • vm.rb

    • Interpreter virtual machine
    • The virtual machine executes AST nodes
  • api.rb

    • Ruby inter-ops
  • ast/nodes.rb

    • AST Node definitions
  • stdlib/kernel.rb

    • Basic wtf data types and kernel functions in Ruby
  • How the interpreter runs your code

    1. Parser runs, and drives the lexer. Generate an AST.
      • Each node knows its children
    2. AST traversal 1
      • Each node knows its parent, and the interpreter knows the entry point
    3. Evaluate the AST node of the "main" function
  • Ruby and wtf objects

    1. Each wtf object type is a WtfType objects
    2. wtf exception is Ruby Wtf::Lang::Exception::WtfError
  • Bindings

    1. Bindings change only at function or module definitions or ensure..rescue block

wtf-interp's People

Contributors

a1exwang avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

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.