diff --git a/README.md b/README.md index e44cb80..e594e72 100644 --- a/README.md +++ b/README.md @@ -5,31 +5,31 @@ Cosmo is a portable scripting language loosely based off of Lua. Cosmo easily al ```lua proto Vector - function __init(self) + func __init(self) self.vector = [] self.x = 0 end - function __index(self, key) + func __index(self, key) return self.vector[key] end - function push(self, val) + func push(self, val) self.vector[self.x++] = val end - function pop(self) + func pop(self) return self.vector[--self.x] end end -var vector = Vector() +let vector = Vector() -for (var i = 0; i < 4; i++) do +for (let i = 0; i < 4; i++) do vector:push(i) end -for (var i = 0; i < 4; i++) do +for (let i = 0; i < 4; i++) do print(vector:pop() .. " : " .. vector[i]) end ``` diff --git a/examples/break.cosmo b/examples/break.cosmo index 3d4fd08..2a5be95 100644 --- a/examples/break.cosmo +++ b/examples/break.cosmo @@ -1,8 +1,8 @@ // just testing continues and breaks -for (var x = 0; x < 700; x++) do - for (var i = 0; true; i++) do - var str = i .. "." .. x +for (let x = 0; x < 700; x++) do + for (let i = 0; true; i++) do + let str = i .. "." .. x if (i == 998) then print(i .. " reached") break // exits the loop @@ -13,9 +13,9 @@ for (var x = 0; x < 700; x++) do end // same example as the for loop but done manually using a while loop - var i = 0 + let i = 0 while true do - var str = i .. "." .. x + let str = i .. "." .. x if (i++ == 998) then print("done") break diff --git a/examples/compare.cosmo b/examples/compare.cosmo index 00319a7..165c5a5 100644 --- a/examples/compare.cosmo +++ b/examples/compare.cosmo @@ -1,20 +1,20 @@ -var strtable = [] -var strLen = 4 // length of all strings to generate -var AByte = "A":byte() // grabs the ascii value of 'A' +let strtable = [] +let strLen = 4 // length of all strings to generate +let AByte = "A":byte() // grabs the ascii value of 'A' proto stringBuilder - function __init(self, length) + func __init(self, length) self.len = length end // we are the iterator object lol - function __iter(self) + func __iter(self) self.x = 0 return self end - function __next(self) - var x = self.x++ + func __next(self) + let x = self.x++ // if we've generated all the possible strings, return nil ending the loop if x >= 26 ^ self.len then @@ -22,8 +22,8 @@ proto stringBuilder end // generate the string - var str = "" - for (var i = 0; i < self.len; i++) do + let str = "" + for (let i = 0; i < self.len; i++) do str = string.char(AByte + (x % 26)) .. str x = math.floor(x / 26) diff --git a/examples/fibtest.cosmo b/examples/fibtest.cosmo index 448410b..6ec52aa 100644 --- a/examples/fibtest.cosmo +++ b/examples/fibtest.cosmo @@ -1,4 +1,4 @@ -local function fib(num) +local func fib(num) if num <= 1 then return num else @@ -6,6 +6,6 @@ local function fib(num) end end -for (var i = 1; i < 40; i++) do +for (let i = 1; i < 40; i++) do print("The fib number of " .. i .. " is " .. fib(i)) end \ No newline at end of file diff --git a/examples/getters_setters.cosmo b/examples/getters_setters.cosmo index 3ec1f0a..7887a4e 100644 --- a/examples/getters_setters.cosmo +++ b/examples/getters_setters.cosmo @@ -1,4 +1,4 @@ -var object = { +let object = { __setter = [ "field1" = function(self, val) print("setter for field1 called!") diff --git a/examples/increment.cosmo b/examples/increment.cosmo index 6a993f2..050dfcc 100644 --- a/examples/increment.cosmo +++ b/examples/increment.cosmo @@ -1,22 +1,22 @@ proto Vector - function __init(self) + func __init(self) self.vector = [] self.x = 0 end - function push(self, val) + func push(self, val) self.vector[self.x++] = val end - function pop(self) + func pop(self) return self.vector[--self.x] end - function __index(self, key) + func __index(self, key) return self.vector[key] end - function __iter(self) + func __iter(self) // you don't *have* to make a new object, i just wanted to show off anonymous functions return {__next = (function(self) return self.vector[self.iterIndex++] @@ -27,9 +27,9 @@ proto Vector end end -var vector = Vector() +let vector = Vector() -for (var i = 0; i < 100000; i++) do +for (let i = 0; i < 100000; i++) do vector:push(i) end diff --git a/examples/iterator.cosmo b/examples/iterator.cosmo index 6a5e294..70a5a31 100644 --- a/examples/iterator.cosmo +++ b/examples/iterator.cosmo @@ -1,14 +1,14 @@ proto Range - function __init(self, x) + func __init(self, x) self.max = x end - function __iter(self) + func __iter(self) self.i = 0 return self end - function __next(self) + func __next(self) if self.i >= self.max then return nil // exit iterator loop end diff --git a/examples/stress.cosmo b/examples/stress.cosmo index 6c76cdf..9b29b0e 100644 --- a/examples/stress.cosmo +++ b/examples/stress.cosmo @@ -1,15 +1,15 @@ proto Test - function __init(self, x) + func __init(self, x) self.x = x end - function print(self) + func print(self) print(self.x) end end // stressing the GC -for (var i = 0; i < 100000; i++) do - var x = Test("Hello world " .. i) +for (let i = 0; i < 100000; i++) do + let x = Test("Hello world " .. i) x:print() end \ No newline at end of file diff --git a/examples/strings.cosmo b/examples/strings.cosmo index d1065dc..08f5de9 100644 --- a/examples/strings.cosmo +++ b/examples/strings.cosmo @@ -1,7 +1,7 @@ -var words = "hello world! this is a sentence with words separated by space":split(" ") +let words = "hello world! this is a sentence with words separated by space":split(" ") -var str = "" -for (var i = 0; i < #words; i++) do +let str = "" +for (let i = 0; i < #words; i++) do str = str .. words[i] print(words[i]) end diff --git a/examples/test.cosmo b/examples/test.cosmo index aac8865..e7fa530 100644 --- a/examples/test.cosmo +++ b/examples/test.cosmo @@ -1,10 +1,10 @@ // crafts a dummy proto proto test - function __init(self) end + func __init(self) end end // instance of test -var obj = test() +let obj = test() test.__index = function(self, key) print("__index called!") diff --git a/examples/testsuite.cosmo b/examples/testsuite.cosmo index cd2107b..1091049 100644 --- a/examples/testsuite.cosmo +++ b/examples/testsuite.cosmo @@ -17,16 +17,16 @@ assert(2 / 5 + 3 / 5 == 1, "PEMDAS check #2 failed!") // iterator test proto Range - function __init(self, x) + func __init(self, x) self.max = x end - function __iter(self) + func __iter(self) self.i = 0 return self end - function __next(self) + func __next(self) if self.i >= self.max then return nil // exit iterator loop end @@ -35,7 +35,7 @@ proto Range end end -var total = 0 +let total = 0 for i in Range(100) do total = total + i end diff --git a/examples/tostring.cosmo b/examples/tostring.cosmo index e6f3859..d7741e7 100644 --- a/examples/tostring.cosmo +++ b/examples/tostring.cosmo @@ -1,27 +1,27 @@ proto test - function __init(self, x) + func __init(self, x) self:setArg(x) end - function __tostring(self) - var total = 1 + func __tostring(self) + let total = 1 - for (var i = self.x; i > 0; i = i - 1) do + for (let i = self.x; i > 0; i = i - 1) do total = total * i; end return "The factorial of " .. self.x .. " is " .. total end - function setArg(self, x) + func setArg(self, x) self.x = x end end -var t = test(1) +let t = test(1) -for (var x = 1; x < 1000; x = x + 1) do - for (var i = 1; i < 100; i = i + 1) do +for (let x = 1; x < 1000; x = x + 1) do + for (let i = 1; i < 100; i = i + 1) do t:setArg(i) print(t) diff --git a/examples/variadic.cosmo b/examples/variadic.cosmo index cab52a6..e458e80 100644 --- a/examples/variadic.cosmo +++ b/examples/variadic.cosmo @@ -1,5 +1,5 @@ // adds all args passed (expects numbers) -function add(start, ...args) +func add(start, ...args) // starting at `start`, add up all numbers passed local total = start for val in args do diff --git a/src/clex.c b/src/clex.c index c1bc874..6682295 100644 --- a/src/clex.c +++ b/src/clex.c @@ -14,7 +14,7 @@ CReservedWord reservedWords[] = { { TOKEN_END, "end", 3}, { TOKEN_FALSE, "false", 5}, { TOKEN_FOR, "for", 3}, - {TOKEN_FUNCTION, "function", 8}, + { TOKEN_FUNC, "func", 4}, { TOKEN_IF, "if", 2}, { TOKEN_IN, "in", 2}, { TOKEN_LOCAL, "local", 5}, @@ -25,7 +25,7 @@ CReservedWord reservedWords[] = { { TOKEN_RETURN, "return", 6}, { TOKEN_THEN, "then", 4}, { TOKEN_TRUE, "true", 4}, - { TOKEN_VAR, "var", 3}, + { TOKEN_LET, "let", 3}, { TOKEN_WHILE, "while", 5} }; diff --git a/src/clex.h b/src/clex.h index ba7a4ce..c8677ef 100644 --- a/src/clex.h +++ b/src/clex.h @@ -57,7 +57,7 @@ typedef enum TOKEN_ELSEIF, TOKEN_END, TOKEN_FOR, - TOKEN_FUNCTION, + TOKEN_FUNC, TOKEN_PROTO, TOKEN_IF, TOKEN_IN, @@ -66,7 +66,7 @@ typedef enum TOKEN_OR, TOKEN_RETURN, TOKEN_THEN, - TOKEN_VAR, + TOKEN_LET, TOKEN_WHILE, TOKEN_ERROR, diff --git a/src/cparse.c b/src/cparse.c index 9ec30c3..f731664 100644 --- a/src/cparse.c +++ b/src/cparse.c @@ -102,7 +102,7 @@ static int expressionPrecedence(CParseState *pstate, int needed, Precedence prec static int expression(CParseState *pstate, int needed, bool forceNeeded); static void statement(CParseState *pstate); static void declaration(CParseState *pstate); -static void function(CParseState *pstate, FunctionType type); +static void parseFunction(CParseState *pstate, FunctionType type); static void expressionStatement(CParseState *pstate); static ParseRule *getRule(CTokenType type); static CObjFunction *endCompiler(CParseState *pstate); @@ -590,36 +590,40 @@ static void group(CParseState *pstate, bool canAssign, Precedence prec) consume(pstate, TOKEN_RIGHT_PAREN, "Expected ')'"); } -static void _etterOP(CParseState *pstate, uint8_t op, int arg) +#define WRITE_GLOBAL_OP(pstate, op, arg) + +static void _etterAB(CParseState *pstate, uint8_t a, int b, bool isGlobal) { - writeu8(pstate, op); - if (op == OP_GETGLOBAL || op == OP_SETGLOBAL) // globals are stored with a u16 - writeu16(pstate, arg); + writeu8(pstate, a); + if (isGlobal) // globals are stored with a u16 + writeu16(pstate, b); else - writeu8(pstate, arg); + writeu8(pstate, b); } static void namedVariable(CParseState *pstate, CToken name, bool canAssign, bool canIncrement, int expectedValues) { - uint8_t opGet, opSet, inc; + uint8_t opGet, opSet, opInc; + bool isGlobal = false; int arg = getLocal(pstate->compiler, &name); if (arg != -1) { - // we found it in out local table! + // we found it in our local table! opGet = OP_GETLOCAL; opSet = OP_SETLOCAL; - inc = OP_INCLOCAL; + opInc = OP_INCLOCAL; } else if ((arg = getUpvalue(pstate, pstate->compiler, &name)) != -1) { opGet = OP_GETUPVAL; opSet = OP_SETUPVAL; - inc = OP_INCUPVAL; + opInc = OP_INCUPVAL; } else { // local & upvalue wasn't found, assume it's a global! arg = identifierConstant(pstate, &name); opGet = OP_GETGLOBAL; opSet = OP_SETGLOBAL; - inc = OP_INCGLOBAL; + opInc = OP_INCGLOBAL; + isGlobal = true; } if (canAssign && match(pstate, TOKEN_COMMA)) { @@ -628,7 +632,7 @@ static void namedVariable(CParseState *pstate, CToken name, bool canAssign, bool consume(pstate, TOKEN_IDENTIFIER, "Expected another identifer!"); namedVariable(pstate, pstate->previous, true, false, expectedValues); - _etterOP(pstate, opSet, arg); + _etterAB(pstate, opSet, arg, isGlobal); valuePopped(pstate, 1); } else if (canAssign && match(pstate, TOKEN_EQUAL)) { expectedValues++; @@ -651,29 +655,21 @@ static void namedVariable(CParseState *pstate, CToken name, bool canAssign, bool writeu8(pstate, OP_NIL); } - _etterOP(pstate, opSet, arg); + _etterAB(pstate, opSet, arg, isGlobal); valuePopped(pstate, 1); } else if (canIncrement && match(pstate, TOKEN_PLUS_PLUS)) { // i++ // now we increment the value - writeu8(pstate, inc); - writeu8(pstate, 128 + 1); // setting signed values in an unsigned int - if (inc == OP_INCGLOBAL) // globals are stored with a u16 - writeu16(pstate, arg); - else - writeu8(pstate, arg); + writeu8(pstate, opInc); + _etterAB(pstate, 128 + 1, arg, isGlobal); // As B(x?) valuePushed(pstate, 1); } else if (canIncrement && match(pstate, TOKEN_MINUS_MINUS)) { // i-- // now we increment the value - writeu8(pstate, inc); - writeu8(pstate, 128 - 1); // setting signed values in an unsigned int - if (inc == OP_INCGLOBAL) // globals are stored with a u16 - writeu16(pstate, arg); - else - writeu8(pstate, arg); + writeu8(pstate, opInc); + _etterAB(pstate, 128 - 1, arg, isGlobal); // As B(x?) valuePushed(pstate, 1); } else { // getter - _etterOP(pstate, opGet, arg); + _etterAB(pstate, opGet, arg, isGlobal); valuePushed(pstate, 1); } } @@ -705,7 +701,7 @@ static void or_(CParseState *pstate, bool canAssign, Precedence prec) static void anonFunction(CParseState *pstate, bool canAssign, Precedence prec) { - function(pstate, FTYPE_FUNCTION); + parseFunction(pstate, FTYPE_FUNCTION); } static void variable(CParseState *pstate, bool canAssign, Precedence prec) @@ -1079,7 +1075,7 @@ ParseRule ruleTable[] = { [TOKEN_ELSEIF] = {NULL, NULL, PREC_NONE}, [TOKEN_END] = {NULL, NULL, PREC_NONE}, [TOKEN_FOR] = {NULL, NULL, PREC_NONE}, - [TOKEN_FUNCTION] = {anonFunction, NULL, PREC_NONE}, + [TOKEN_FUNC] = {anonFunction, NULL, PREC_NONE}, [TOKEN_PROTO] = {NULL, NULL, PREC_NONE}, [TOKEN_IF] = {NULL, NULL, PREC_NONE}, [TOKEN_IN] = {NULL, NULL, PREC_NONE}, @@ -1090,7 +1086,7 @@ ParseRule ruleTable[] = { [TOKEN_THEN] = {NULL, NULL, PREC_NONE}, [TOKEN_WHILE] = {NULL, NULL, PREC_NONE}, [TOKEN_ERROR] = {NULL, NULL, PREC_NONE}, - [TOKEN_VAR] = {NULL, NULL, PREC_NONE}, + [TOKEN_LET] = {NULL, NULL, PREC_NONE}, [TOKEN_EOF] = {NULL, NULL, PREC_NONE} }; @@ -1182,7 +1178,7 @@ static void _proto(CParseState *pstate) int entries = 0; while (!match(pstate, TOKEN_END) && !match(pstate, TOKEN_EOF) && !pstate->hadError) { - if (match(pstate, TOKEN_FUNCTION)) { + if (match(pstate, TOKEN_FUNC)) { // define method consume(pstate, TOKEN_IDENTIFIER, "Expected identifier for method!"); uint16_t fieldIdent = identifierConstant(pstate, &pstate->previous); @@ -1191,7 +1187,7 @@ static void _proto(CParseState *pstate) writeu8(pstate, OP_LOADCONST); writeu16(pstate, fieldIdent); - function(pstate, FTYPE_METHOD); + parseFunction(pstate, FTYPE_METHOD); valuePopped(pstate, 1); } else { errorAtCurrent(pstate, "Illegal syntax!"); @@ -1409,7 +1405,7 @@ static void whileStatement(CParseState *pstate) patchJmp(pstate, exitJump); } -static void function(CParseState *pstate, FunctionType type) +static void parseFunction(CParseState *pstate, FunctionType type) { CCompilerState compiler; initCompilerState(pstate, &compiler, type, pstate->compiler); @@ -1475,7 +1471,7 @@ static void functionDeclaration(CParseState *pstate) if (pstate->compiler->scopeDepth > 0) markInitialized(pstate, var); - function(pstate, FTYPE_FUNCTION); + parseFunction(pstate, FTYPE_FUNCTION); defineVariable(pstate, var, false); } @@ -1506,12 +1502,12 @@ static void returnStatement(CParseState *pstate) valuePopped(pstate, rvalues); } -static void localFunction(CParseState *pstate) +static void localparseFunction(CParseState *pstate) { uint16_t var = parseVariable(pstate, "Expected identifer!", true); markInitialized(pstate, var); - function(pstate, FTYPE_FUNCTION); + parseFunction(pstate, FTYPE_FUNCTION); defineVariable(pstate, var, true); } @@ -1732,12 +1728,12 @@ static void expressionStatement(CParseState *pstate) { int savedPushed = pstate->compiler->pushedValues; - if (match(pstate, TOKEN_VAR)) { + if (match(pstate, TOKEN_LET)) { varDeclaration(pstate, false, 0); } else if (match(pstate, TOKEN_LOCAL)) { // force declare a local - if (match(pstate, TOKEN_FUNCTION)) - localFunction(pstate); // force a local function declaration + if (match(pstate, TOKEN_FUNC)) + localparseFunction(pstate); // force a local function declaration else if (match(pstate, TOKEN_PROTO)) localProto(pstate); // force a local proto declaration else @@ -1752,7 +1748,7 @@ static void expressionStatement(CParseState *pstate) whileStatement(pstate); } else if (match(pstate, TOKEN_FOR)) { forLoop(pstate); - } else if (match(pstate, TOKEN_FUNCTION)) { + } else if (match(pstate, TOKEN_FUNC)) { functionDeclaration(pstate); } else if (match(pstate, TOKEN_PROTO)) { protoDeclaration(pstate);