Check out our super cool website!
Ever wish that JavaScript had fewer symbols and more dogs? We did, so we made PawvaScript!
PawvaScript is an object-oriented scripting language designed to make JavaScript more programmer-friendly (so friendly that your dog could learn it, probably). PawvaScript draws on many fundamentals from JavaScript but replaces confusing symbols with clear and (dog-friendly) readable terms, adds types (like TypeScript) to help with debugging, and throws in some paw-sitively awesome dog-related keywords just for fun and tail wags.
Check out the full Ohm description of the PawvaScript grammar here!
- Language for scripting
- Object-Oriented
- breeds are what we call classes!
- Static typing
- Functions
- we call them tricks!
- 5 basic types
- leash (string)
- goodBoy (boolean)
- toeBeans (number)
- pack (list)
- kennel (map)
- 5 kinds of loops
- Forever
- Fixed
- While
- For
- ForEach
- Conditional Statements
- Spread/peanutButter syntax
- Single and multi-line comments
Let's start with a classic.
PawvaScript | JavaScript |
---|---|
woof "Hello, World!"; bark "my ball!"; howl "uh-oh"; |
console.log("Hello, World!";) console.log("my ball!".toUpperCase()); console.error("uh-oh"); |
PawvaScript's primitive types are similar to JavaScripts, and it also has data structures like Python's lists and dictionaries.
PawvaScript | Javascript/Python |
---|---|
goodBoy | boolean |
leash | string |
toeBeans | number |
trick | function |
pack | array/list |
kennel | map/dictionary |
breed | class/object |
Variables are declared with their type.
PawvaScript | JavaScript |
---|---|
leash dogName is "CeCe"; toeBeans dogAge is 12; goodBoy isGoodBoy is good; goodBoy isNaughtyDoggo is bad; |
let dogName = "CeCe"; let dogAge = 12; let isGoodBoy = true; let isNaughtyDoggo = false; |
pack[leash] dogNames is ["CeCe", "Fluffy"]; kennel[leash:toeBeans] dogAges is ["CeCe": 1, "Fluffy": 2]; |
let dogNames = ["CeCe", "Fluffy"]; let dogAges = {"CeCe": 1, "Fluffy": 2}; |
toeBeans cuteness; !!! Default value is 0 !!! cuteness is 100; |
let cuteness = 0; cuteness = 100; |
!!! cat is the equivalent of null. !!! !!! Any type can have the value cat !!! leash theBestestDog is cat; |
|
PawvaScript supports leash interpolation and concetation:
PawvaScript | JavaScript |
---|---|
leash dogName is "Ce" with "Ce"; leash sentence is "![dogName] is the best dog"; |
let dogName = "Ce" + "Ce"; let sentence = `${dogName} is the best dog"; |
Packs are the PawvaScript equivalent of lists in Python or arrays in JavaScript:
PawvaScript | JavaScript |
---|---|
pack[leash] goodDogs is ["CeCe", "Buster", "Muffin"]; pack[toeBeans] ages is [1, 1, 2]; |
let goodDogs = ["CeCe", "Buster", "Muffin"]; let ages = [1, 1, 2]; |
!!! "without" removes elements from a pack !!! pack[leash] bestDogs is goodDogs without "Muffin"; |
|
!!! "peanutButter" is the spread operator !!! pack[leash] smallDogs is ["Tiny", "Teenie", "Boo"]; pack[leash] bigDogs is ["Boofer", "Woofer," "Mo"]; pack[leash] allDogs is [ peanutButter smallDogs, peanutButter bigDogs ]; woof allDogs; !!! ["Tiny", "Teenie", "Boo", "Boofer", "Woofer", "Mo"] !!! |
let smallDogs = ["Tiny", "Teenie", "Boo"]; let bigDogs = ["Boofer", "Woofer", "Mo"]; let allDogs = [ ...smallDogs, ...bigDogs ]; |
Kennels are data structures like Python dictionaries.
PawvaScript | JavaScript |
---|---|
kennel[leash:leash] goodDogs is [ "CeCe": "German Shepherd", "Buster": "Golden Doodle", "Mo": "Potato" ]; kennel[leash:toeBeans] ages is ["CeCe": 1, "Buster": 1, "Mo": 5]; |
let goodDogs = { "CeCe": "German Shepherd", "Buster": "Golden Doodle", "Mo": "Potato" }; let ages = {CeCe: 1, Buster: 1, Mo: 5}; |
Wanna compare stuff?
PawvaScript | JavaScript |
---|---|
goodBoy a is x equals y; a is x notEquals y; a is x isGreaterThan y; a is x isLessThan y; a is x isAtLeast y; a is x isAtMost y; |
let a = x === y; a = x !== y; let a = x > y; a = x < y; let a = x >= y; a = x <= y; |
PawvaScript | JavaScript |
---|---|
toeBeans a is x + y; a is x - y; a is x * y; a is x / y; a is x mod y; a is x!; a is -x; |
a = x + y; a = x - y; a = x * y; a = x / y; a = x % y; a = x!; a = -x; |
PawvaScript | JavaScript |
---|---|
if x isAtLeast y then: leash dogName is "CeCe"; else: leash dogName is "Buster"; tail |
if (x <= y) { let dogName = "CeCe"; else { let dogName = "Buster"; } |
|
if (x !== y) { console.log("CeCe is kinda cute"); else if (x > y) { console.log("CeCe is pretty cute"); else if (x < y) { console.log("Okay, CeCe is really cute"); else { console.log("CeCe is the cutest of the cutest"); } |
Let's write some comments!
PawvaScript | JavaScript |
---|---|
!!! I'm a one line comment !!! !!! I'm a multiline comment !!! |
// I'm a comment /* I'm a multiline comment */ |
Forever Loop
PawvaScript | JavaScript |
---|---|
chase: woof "I run forever!"; tail |
while (true) { console.log("I run forever\!"); } |
Fixed Loop
PawvaScript | JavaScript |
---|---|
chase 5 times: woof "Stay."; tail |
for (let i = 0; i < 5; i++) { console.log("Stay."); } |
While Loop
PawvaScript | JavaScript |
---|---|
chase while x isAtMost 5: woof x; tail |
while (x <= 5) { console.log(x); } |
For Loop
PawvaScript | JavaScript |
---|---|
chase toeBeans i is 0 by i*2 while i isLessThan 10: woof i; tail |
for (let i = 0; i < 10; i *= 2) { console.log(i); } |
For Each Loop
PawvaScript | JavaScript |
---|---|
chase element through myPack: woof element; tail |
for (let element of myArray) { console.log(element); } |
Use poop
and walkies
to break
and continue
, respectively.
PawvaScript | JavaScript |
---|---|
chase element through myPack: if element equals cat then: poop; else if element equals "CeCe" then: walkies; tail; woof element; tail |
for (let element of myArray) { if (element === null) { break; } else if (element === "CeCe") { continue; } console.log(element); } |
Let's find the greatest common divisor between two toeBeans!
PawvaScript | JavaScript |
---|---|
trick gcd chews[toeBeans:num1, toeBeans:num2] fetches toeBeans: toeBeans remainder; chase while (a mod b) isGreaterThan 0: remainder is (a mod b); a is b; b is remainder; tail; give a; tail |
function gcd(num1, num2) { let remainder; while ((num1 % num2) > 0) { remainder = a % b; a = b; b = remainder; } return a; } |
toeBeans a is 8; toeBeans b is 12; toeBeans c is gcd(a, b); |
let a = 8; let b = 12; let c = gcd(a, b); |
The classic Fibonacci function to get the nth term of the Fibonacci sequence:
PawvaScript | JavaScript |
---|---|
trick fib chews[toeBeans:n] fetches toeBeans: if n isAtMost 1 then: give n; else: give fib(n-1) + fib(n-2); tail tail |
function fib(n) { if (n <=1) { return n; } else { return fib(n-1) + fib(n-2); } } |
toeBeans huzzah is fib(100); |
let huzzah = fib(100); |
Let's make an owner breed!
PawvaScript | JavaScript |
---|---|
|
class Owner { constructor(dogName) { this.dogName = dogName; } introduceDog() { console.log(`My dog's name is ${this.dogName}`; } command() { return `${this.dogName}, stay!`; } } |
- The target and source of a variable declaration must have the same type.
- The target and source of an assignment statement must have the same type.
- Types and functions cannot be declared in loops.
- Variables can only be declared once in the same block.
- Conditions in if statements must be booleans.
- Conditions in loops must be booleans.
- For loop variables must evaluate to a number.
- Through loops can only be used on lists. (We hope to expand this functionality to other types soon!)
- A through loop's variable cannot be changed in the body of the loop (read-only).
- Types can only have one constructor.
- A constructor's identifier must match the identifier of the type it constructs.
- The parameters of a constructor must be fields in their type.
- A constructor can only return the breedType it is a part of.
- If a function's signature contains a return type, the function must and can only return an object of the return type.
- Functions must be called with the same number of arguments as described in the function signature.
- Each function argument must be the same type as argument in that same positiion in the function signature.
- Spreads can only be used on list members that are also lists, and the member types of the lists must be the same.
- A dictionary's keys must all have the same type and its values must also all be of the same type.
- The unary operators "-" and "!" can only be used with numbers.
- The operator "not" can only be used with booleans.
- The binary operators "-", "+", "*", and "/" can only be used with numbers on either side.
- The operators "&" and "|" can only be used with booleans on either side.
- The operators "isGreaterThan", "isAtLeast", "isAtMost", "isLessThan", "equals", and "notEquals" can only be used with numbers and strings and the types must match on both sides.
- The operators "with" and "without" can only be used with strings and lists and the types must match on both sides.
- The "at" operator can only be used with a list on the left and numbers on the right.
- The "of" operator can only be used with a dictionary on the left and numbers on the right and the key used must match the type of the keys in the dictionary.
- Give statements can only be used in functions, methods, and loops.
- Break and continue statements can only be used in loops.
Happy PawvaScript coding! Remember: Good Dogs only!