{"id":15439106,"url":"https://github.com/maxbarsukov/waddle","last_synced_at":"2025-04-19T18:33:14.139Z","repository":{"id":57397000,"uuid":"444847599","full_name":"maxbarsukov/waddle","owner":"maxbarsukov","description":"🦩 Object-oriented static-typing language","archived":false,"fork":false,"pushed_at":"2022-01-19T19:25:07.000Z","size":544,"stargazers_count":4,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T11:41:36.930Z","etag":null,"topics":["interpreter","static-typing","type-inference"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/waddle","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maxbarsukov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-05T15:08:39.000Z","updated_at":"2024-02-08T12:51:52.000Z","dependencies_parsed_at":"2022-09-13T10:22:17.614Z","dependency_job_id":null,"html_url":"https://github.com/maxbarsukov/waddle","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxbarsukov%2Fwaddle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxbarsukov%2Fwaddle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxbarsukov%2Fwaddle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxbarsukov%2Fwaddle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maxbarsukov","download_url":"https://codeload.github.com/maxbarsukov/waddle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249765239,"owners_count":21322388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["interpreter","static-typing","type-inference"],"created_at":"2024-10-01T19:02:34.624Z","updated_at":"2025-04-19T18:33:14.118Z","avatar_url":"https://github.com/maxbarsukov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Waddle\n\n[![Build Status](https://github.com/maxbarsukov/waddle/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/maxbarsukov/waddle/actions/workflows/main.yml)\n[![Codecov](https://codecov.io/gh/maxbarsukov/waddle/branch/master/graph/badge.svg?token=DAVZ1WBI7Q)](https://codecov.io/gh/maxbarsukov/waddle)\n![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/maxbarsukov/waddle)\n\n[![NPM version](https://img.shields.io/npm/v/waddle)](https://www.npmjs.com/package/waddle)\n[![NPM downloads](https://img.shields.io/npm/dy/waddle)](https://www.npmjs.com/package/waddle)\n[![License](https://img.shields.io/npm/l/waddle)](https://github.com/maxbarsukov/waddle/blob/master/LICENSE.txt)\n\n***Waddle*** is a strongly-typed *object-oriented* toy programming language whose syntax is partially inspired by **Kotlin** and **Ruby**.\n\n- Object-oriented language.\n- Statically typed language with **type inference**.\n- The *last value evaluated in a method is its return value*.\n- ***Everything is an object***.\n\n## Documentation\n\nHave a look in the [examples](https://github.com/maxbarsukov/waddle/tree/master/examples) directory to learn more.\n\n## Installation\n\n    $ npm install -g waddle\n\n## Usage\n\nRun **Repl**:\n```bash\nwaddle\n```\n\nor run file:\n```bash\nwaddle examples/hello.waddle\n```\n\n## Examples of code\n\nBasic:\n```kotlin\n// comment\n\n\"This is a string\" // res0: String = \"This is a string\"\n\"Hello, \" + \"Max\" // res1: String = \"Hello, Max\"\n\n1 + 2 // =\u003e res2: Int = 3\n-2 * 3 + (1 - 2) // res3: Int = -7\n\n2e4 // res4: Double = 20000\n3.14 // res5: Double = 3.14\n\n10.toString() // res6: String = \"10\"\n15.+(1).*(3) // res7: Int = 48\n\nif (true) \"true\" else \"false\" // res8: String = \"true\"\nif (\"hello\" == \"he\" + \"llo\") {\n  42\n} else {\n  -1 \n} // res9: Int = 42\n\n\"hello\".length() // res10: Int = 5\n\"how are you?\".at(2) // res11: String = \"w\"\n\"abscde\".replace(\"a\", \"111\") // res12: String = \"111bscde\"\n\nnull // res13: Null = null\nnull.toString()\n\n100.unary_-() // res14: Int = -100\n\n1.instanceOf(\"Int\") //res15: Bool = true\n1.instanceOf(\"String\") //res16: Bool = false\n```\n\nBooleans  :\n```kotlin\ntrue // res0: Bool = true\nfalse // res1: Bool = false\n!false // res2: Bool = true\n1 \u003e= 3 // res4: Bool = false\n2 == \"hey\" // res5: Bool = false\ntrue || false // res6: Bool = true\ntrue \u0026\u0026 true // res7: Bool = true\nfalse.unary_!() // res8: Bool = true\n```\n\nLet:\n```kotlin\nlet message: String = \"Hello, World!\" in {\n  IO.println(message)\n}\n// type inference\nlet message = \"Hello, World!\" in {\n  IO.println(message)\n}\n\nlet a = 2, b = 3 in {\n  a + b\n} // res0: Int = 5\n\nlet a = 2, b = 3 in a + b // res1: Int = 5\n```\n\nWhile:\n```kotlin\nlet i = 1 in {\n  while (i \u003c= 10) {\n    IO.println(i)\n    i += 1\n  }\n} // 1 2 3 4 5 6 7 8 9 10\n```\n\nVariables:\n```kotlin\nvar message: String = \"Hello\" // message: String = Hello!\n// type inference\nvar message1 = \"Hello, World!\" // message1: String = Hello!\n```\n\nFunctions:\n```kotlin\ndef add(a: Int, b: Int): Int = {\n  a + b\n}\n// add(a: Int, b: Int): Int\nadd(42, 1) // res0: Int = 43\n\ndef add2(a: Int, b: Int): Int = a + b\n// add2(a: Int, b: Int): Int\nadd2(42, 1) // res0: Int = 43\n\ndef sayHi() = IO.println(\"Hi!\")\nsayHi() // Hi!\n```\n\nIO:\n```kotlin\nIO.println(1 + 2) // 3\nIO.println(-2 * 3 + (1 - 2)) // -7\n```\n\nMath:\n```kotlin\nMath // Math: Math$ = Math$@0\nMath.pi() // res0: Double = 3.141592653589793\nMath.log2(16) // res1: Double = 4\nMath.max(16, 42) // res10: Int = 42\n```\n\nOOP:\n```kotlin\nclass Person(firstname: String, lastname: String) {\n  var age: Int = 0\n  \n  def firstname(): String = {\n    firstname\n  }\n  \n  def setFirstname(name: String) = {\n    firstname = name\n  }\n  \n  def whoIsPrivate() = {\n    IO.println(somePrivateMethod())\n  }\n  \n  // override func\n  override def toString(): String = {\n    \"Person(\" + firstname + \", \" + lastname + \")\"\n   }\n  \n  // functions are public by default\n  // private func\n  private def somePrivateMethod(): String = \"I'm private!\"\n}\n\n// inheritence\nclass Employee(\n  firstname: String,\n  lastname: String,\n  company: String\n) extends Person(firstname, lastname) {\n  def company(): String = company\n  def setCompany(c: String) = company = c\n}\n\nvar person = new Person(\"John\", \"Doe\") // person: Person = Person(John, Doe)\n\nperson.whoIsPrivate() // I'm private!\nIO.println(person) // Person(John, Doe)\n\nperson.firstname() // res8: String = \"John\"\nperson.setFirstname(\"Max\")\nperson.firstname() // res9: String = \"Max\"\n\nvar employee = new Employee(\"John\", \"Doe\", \"company\")\nemployee.firstname() // res10: String = \"John\"\nemployee.company() // res11: String = \"company\"\n```\n\nFraction class in ***Waddle***:\n```kotlin\nclass Fraction(n: Int, d: Int) {\n  var g: Int = gcd(Math.abs(n), Math.abs(d))\n\n  var num: Int = n / g\n  var den: Int = d / g\n\n  def num(): Int = num\n  def setNum(n: Int) = num = n / gcd(Math.abs(n), Math.abs(den))\n\n  def den(): Int = den\n  def setDen(d: Int) = den = d / gcd(Math.abs(num), Math.abs(d))\n\n  def +(that: Fraction): Fraction = new Fraction(\n        num * that.den() + den * that.num(),\n        den * that.den()\n      )\n\n  def +(that: Int): Fraction = this + new Fraction(that, 1)\n\n  def -(that: Fraction): Fraction = new Fraction(\n        num * that.den() - den * that.num(),\n        den * that.den()\n      )\n\n  def -(that: Int): Fraction = this - new Fraction(that, 1)\n  def *(that: Fraction): Fraction = new Fraction(num * that.num(), den * that.den())\n  def *(that: Int): Fraction = this * new Fraction(that, 1)\n  def /(that: Fraction): Fraction = this * new Fraction(that.den(), that.num())\n  def /(that: Int): Fraction = this / new Fraction(that, 1)\n\n  override def ==(that: Object): Bool = {\n      if (!that.instanceOf(\"Fraction\"))\n          false\n      else {\n          let frac = that as Fraction in {\n              num == frac.num() \u0026\u0026 den == frac.den()\n          }\n      }\n  }\n\n  override def toString(): String = num + if (den \u003e 1) \"/\" + den else \"\"\n\n  private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)\n}\n```\n\nSuper:\n```kotlin\nclass A {\n  def a(): String = super.toString()\n}\n\nIO.println(new A().a()) // A@0\n```\n\nThis:\n```kotlin\nclass B {\n  def b(): B = this\n}\n\nvar b = new B()\nIO.println(b.b()) // B@2\nIO.println(b.b().b().b().b().b()) // B@3\n```\n\nLists: [examples/list.waddle](https://github.com/maxbarsukov/waddle/blob/master/examples/list.waddle)\n\nModule system:\n```javascript\n// dir/my_module.waddle\n// Use `export` keyword to export class\nexport class A {\n  def a(): Int = 42\n}\n\nexport class B {\n  def b(): Int = 13\n}\n\n// main.waddle\nimport A, B from \"./dir/my_module\"\n// or\n// import A, B from \"./dir/my_module.waddle\"\n// or\n// import A, B from \"./dir\" // to import all files recursively\n\nIO.println(new A().a()) // 42\nIO.println(new B().b()) // 13\n```\n\nBuiltin modules:\n```python\nimport LinkedList from \"collections/list\"\n// or just ...`from \"collections\"`\n\nIO.println(new LinkedList()) // []\n```\n\n## Building\n\n### Pre-reqs\n\nTo build and run this app locally you will need a few things:\n\n- Install [Node.js](https://nodejs.org/en/);\n\n### Getting start\n\n- Clone the repository\n```bash\ngit clone --depth=1 https://github.com/maxbarsukov/waddle.git\n```\n- Install dependencies\n```bash\ncd waddle\nnpm install\n```\n- Run\n```bash\nnpm run start\n````\n- **Tests**\n```bash\nnpm test\n```\n- **Linting**\n```bash\nnpm run lint\n```\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/maxbarsukov/waddle. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/maxbarsukov/waddle/blob/master/CODE_OF_CONDUCT.md).\n\n## License\n\nThe package is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the Waddle project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/maxbarsukov/waddle/blob/master/CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxbarsukov%2Fwaddle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaxbarsukov%2Fwaddle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxbarsukov%2Fwaddle/lists"}