Skip to content

Commit

Permalink
minimization optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
maniospas committed Oct 23, 2024
1 parent 876f22a commit 19c1ae5
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 43 deletions.
Binary file modified blombly.exe
Binary file not shown.
2 changes: 0 additions & 2 deletions docs/advanced/libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ detailed here.

## env

**Currently the env library is not working properly**

This library provides an alternative to traditional import statements
helps organizes and versions dependencies.
It essentially forms a programmatically-managed
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced/semitypes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ or are transformed to appropriate data, therefore introducing type correctness g
for subsequent code. At its core, this is equivalent to expressing
method calls of one argument. However, code writting is drastically simplified:

- Conversions are easily chained using much fewer symbols.
- Conversions are chained using fewer symbols and less nesting.
- Conversions are read as variable type semantics, which we dub semi-types.

## Type conversion
Expand Down
41 changes: 41 additions & 0 deletions libs/def/.bb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
final def::INFO as {
name = "def";
author = "Emmanouil Krasanakis";
license = "Apache 2.0";
version = "1.0";
release = 0;
year = 2024;
doc = "
\n Introduces class and function definition semantics
\n that make code look similar to other languages.
\n
\n def::fn
\n -------
\n Defines a final code block with a given name and
\n arguments. Positional arguments (in fact, a runnable
\n default code block) are also supported like below.
\n Additional arguments can also be provided.
\n
\n | def::fn adder(x, y|bias=0) \{return x+y+bias\}
\n
\n def::class
\n Defines a class through its constructor. The
\n constructor is final and callable. Here is an
\n example:
\n
\n | def::class Dog(name) \{def::uses name;\}
";
}


#include "libs/def/fn"
#include "libs/def/class"

// enables the
#macro {def::simplify;} as {
#macro {fn} as {def::fn}
#macro {module} as {def::module}
#macro {abstract} as {def::abstract}
#macro {uses} as {def::uses}
#macro {class} as {def::class}
}
12 changes: 6 additions & 6 deletions libs/oop/class.bb → libs/def/class.bb
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@

// class definition
#macro (oop::class @name(@args) {@code}) = {
final @name(@args) = {
#macro {def::class @name(@args) {@code}} as {
def::fn @name(@args) {
#spec type="class";
#spec name=#stringify(@name);
return new {
final type = @name;
oop::uses @name;
def::uses @name;
@code
}
}
}

// uses definitition
#macro (oop::uses @name;) = {
#macro {def::uses @name;} as {
final @name = @name;
}

// abstract definition
#macro (oop::abstract @name {@code}) = {
#macro {def::abstract @name {@code}} as {
final @name = {
#spec type="abstract";
#spec name=#stringify(@name);
Expand All @@ -27,7 +27,7 @@
}

// module definition
#macro (oop::module @name {@code}) = {
#macro {def::module @name {@code}} as {
final @name = new {
final type="module";
final name=#stringify(@name);
Expand Down
8 changes: 4 additions & 4 deletions libs/oop/fn.bb → libs/def/fn.bb
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
// function with only positional arguments (overriden by subsequent versions)
#macro (oop::fn @name(@args){@code}) = {
#macro {def::fn @name(@args){@code}} as {
final @name(@args) = {
#spec type="fn";
#spec name=#stringify(@name);
@code
}
}
// function with no arguments
#macro (oop::fn @name(){@code}) = {
#macro {def::fn @name(){@code}} as {
final @name = {
#spec type="fn";
#spec name=#stringify(@name);
@code
}
}
// function with defaults
#macro (oop::fn @name(@args | @defaults){@code}) = {
#macro {def::fn @name(@args | @defaults){@code}} as {
final @name(@args) = {
#spec type="fn";
#spec name=#stringify(@name);
Expand All @@ -24,7 +24,7 @@
}
}
// function with only defaults (identified because it has an assignment)
// #macro (oop::fn @name(@arg = @defaults){@code}) = {
// #macro (def::fn @name(@arg = @defaults){@code}) = {
// final @name = {
// #spec type="fn";
// #spec name=#stringify(@name);
Expand Down
30 changes: 22 additions & 8 deletions libs/env.bb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ final env::INFO as {
name = "env";
author = "Emmanouil Krasanakis";
license = "Apache 2.0";
version = "1.0";
version = "1.1";
release = 0;
year = 2024;
doc = "
Expand All @@ -18,7 +18,7 @@ final env::INFO as {
\n - env::include(library);
\n Includes a library by its name (as a string).
\n
\n - env::include(library|version=...;minrelease=...);
\n - env::include(library|version=..;minrelease=..);
\n Includes a library with a specific version and
\n minimum release number. You may ommit the latter.
\n
Expand Down Expand Up @@ -64,12 +64,16 @@ final env::dependencies = list(new{env::INFO:});
// check whether imnported library satisfies the version or release
while(dependency as std::next(#of iter(env::dependencies)))
if([email protected]) {
if((version as version) and (dependency.version!=version))
fail("Incompatible versions for library {@lib}:
\nimported version is {dependency.version} but {version} is required.");
if((minrelease as minrelease) and (dependency.release<minrelease))
fail("Incompatible versions for library {@lib} version {version}:
\nimported minor release is {dependency.release} but a minimum of {minrelease} is required.");
if(version as version)
if(dependency.version!=version)
fail("Incompatible versions for library {@lib}:
\nimported version is {dependency.version} but {version} is required.");
if(minrelease as minrelease) {
if(dependency.release<minrelease)
fail("Incompatible versions for library {@lib} version {version}:
\nimported minor release is {dependency.release} but a minimum of {minrelease} is required.");
dependency.release = minrelease;
}
}
}
}
Expand Down Expand Up @@ -98,3 +102,13 @@ final env::versions() = {
desc = desc + env::hbar;
print(desc);
}
// print the full include statement
final env::export() = {
ljust = {size=7;env::ljust:}
desc = env::hbar + "\n#include \"libs/env\"\n";
while(dependency as std::next(#of std::iter(env::dependencies)))
desc = desc + "env::include({dependency.name|ljust} | version={dependency.version}, minrelease={dependency.release});\n";
desc = desc + env::hbar;
print(desc);
}
6 changes: 3 additions & 3 deletions libs/loop.bb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ final loop::INFO as {
name = "loop";
author = "Emmanouil Krasanakis";
license = "Apache 2.0";
version = "1.1";
version = "1.2";
release = 0;
year = 2024;
doc = "
Expand Down Expand Up @@ -41,8 +41,8 @@ final loop::INFO as {
\n | inc = loop::lambda(x->x+1);
\n | print(inc(0)); // 1
\n
\n loop:tolist
\n -----------
\n loop::tolist
\n ------------
\n Gathers all the values of an iterable and converts
\n them to a list. There are two variations to optionally
\n apply element-wise transforms to the lists with the
Expand Down
11 changes: 0 additions & 11 deletions libs/oop/.bb

This file was deleted.

3 changes: 2 additions & 1 deletion libs/symb.bb
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ final symb::INFO as {
";
}

#macro {λ} as {symb::lambda}
#macro {λ} as {symb::lambda}
#macro {π} as {symb::pi}
11 changes: 9 additions & 2 deletions main.bb
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
x = "fff" | float | int;
print(x);
#include "libs/env"
env::include(loop);
env::include(def);

def::fn test(x,y) {
return x+y;
}

print(test(1,2));
56 changes: 52 additions & 4 deletions main.bbvm
Original file line number Diff line number Diff line change
@@ -1,4 +1,52 @@
BUILTIN _bb2 "fff"
float _bb1 _bb2
int x _bb1
print # x
BEGIN _bb4
BUILTIN name "env"
END
AS env::INFO _bb4
final # env::INFO
BEGIN _bb54
inline _bb55 env::INFO
return # this
END
new _bb52 _bb54
list env::dependencies _bb52
final # env::dependencies
BEGIN _bb132
BUILTIN name "loop"
END
AS loop::INFO _bb132
final # loop::INFO
BEGIN _bb143
inline _bb144 loop::INFO
return # this
END
new _bbmacro2 _bb143
push # env::dependencies _bbmacro2
BEGIN _bb145
BUILTIN name "def"
END
AS def::INFO _bb145
final # def::INFO
BEGIN _bb156
inline _bb157 def::INFO
return # this
END
new _bbmacro3 _bb156
push # env::dependencies _bbmacro3
BEGIN _bb158
next x args
next y args
add _bb159 x y
return # _bb159
END
IS test _bb158
final # test
setfinal # test name test
BUILTIN _bb160 "fn"
setfinal # test type _bb160
BEGIN _bb162
BUILTIN _bb163 I1
BUILTIN _bb164 I2
list args _bb163 _bb164
END
call _bb161 _bb162 test
print # _bb161
66 changes: 66 additions & 0 deletions src/utils/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,73 @@ void optimize(const std::string& source, const std::string& destination) {
--i;
}
}*/

// remove unused methods
int changes = -1;
while(changes!=0) {
std::unordered_map<std::string, int> symbolUsageCount;
for (const auto& command : program) {
if(!command->enabled || command->args.size()==0)
continue;
if(command->args[0]=="END" || command->args[0]=="BEGIN" || command->args[0]=="BEGINFINAL" || command->args[0]=="final" || command->args[0]=="exists")
continue;
for (size_t j = 2; j < command->args.size(); ++j) {
const std::string& symbol = command->args[j];
if (symbol == "LAST")
bberror("Internal error: the LAST keyword has been deprecated");
if (symbol != "#")
symbolUsageCount[symbol]++;
}
}
changes = 0;
for (int i=0;i<program.size();++i) {
auto& command = program[i];
if(!command->enabled)
continue;
if(command->args[0]=="exists" && command->args.size() && symbolUsageCount[command->args[1]]==0) {
command->enabled = false;
++changes;
continue;
}
if(command->args.size()<=1)
continue;
if(command->args[0]=="final" && command->args.size()>=3 && symbolUsageCount[command->args[2]]==0) {
command->enabled = false;
++changes;
continue;
}
if(command->args[0]=="BUILTIN" && command->args.size() && symbolUsageCount[command->args[1]]==0) {
command->enabled = false;
++changes;
continue;
}
if((command->args[0]=="IS" || command->args[0]=="AS") && command->args.size() && symbolUsageCount[command->args[1]]==0) {
command->enabled = false;
++changes;
continue;
}
if(command->args[0]!="BEGIN" && command->args[0]!="BEGINFINAL")
continue;
if(symbolUsageCount[command->args[1]]!=0)
continue;
// std::cout << "removing "<<command->args[0]<<" "<<command->args[1]<<" "<<command->enabled<<"\n";
i = i+1;
int depth = 1;
++changes;
command->enabled = false;
while(i<program.size()) {
program[i]->enabled = false;
if(program[i]->args[0]=="BEGIN" || program[i]->args[0]=="BEGINFINAL")
depth += 1;
if(program[i]->args[0]=="END")
depth -= 1;
if(depth==0)
break;
++i;
}
}

}


// save the compiled code to the destination file
Expand Down
7 changes: 6 additions & 1 deletion src/utils/tokenizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ std::vector<Token> tokenize(const std::string& text, const std::string& file) {
else
inComment = false;
}
if (c == '/' && i < text.size() - 1 && text[i + 1] == '/') {
if (c == '/' && i < text.size() - 1 && text[i + 1] == '/' && !inString) {
wordStream.str(""); // Clear the stream
inComment = true;
continue;
Expand Down Expand Up @@ -170,6 +170,11 @@ std::vector<Token> tokenize(const std::string& text, const std::string& file) {
}

if (inString) {
if (c == '\\' && i<text.size()-1 && (text[i+1]=='{' || text[i+1]=='}' || text[i+1]=='"')) {
wordStream << text[i+1];
i += 1;
continue;
}
if (c == '{') {
// Add current string
wordStream << "\"";
Expand Down

0 comments on commit 19c1ae5

Please sign in to comment.