import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class SLB_COMPILER
{
/*/
*
1.0.0
---General---
Compiler for my own simple programming language SLB (Simplified Line Base).
In this setting executable file of this compiler must be in directory "C://SLBDIR".
In this setting must be code of SLB written in file called "SLB sheet.txt" and this text file must be in folder with compiler ("C://SLBDIR").
Additionally SLB requires secondary text file called "Fnc.txt" as a support file to perform various operations ("C://SLBDIR").
1.1.0
---Syntax---
1.1.1
[Declaration]
To acknowledge compiler that we are using SLB, first line of text file must equal to ::use_lb .
1.1.2
[Variables]
Declaration of variables contains 5 basic points: a)Declaration operator %
b)Variable name
c)Value assigner :
d)Variable value
e)Key ?
Usage:
--------------------------------------
| %myvar:6? -variable declaration |
--------------------------------------
Symbol % acknowledges compiler, that we are about to declare variable.
Text "myvar" compiler considers as variable name.
Symbol : signalises to compiler to get ready to read variable value.
Symbol ? signalises execution of declaration and is call symbol of variable in operations aswell.
(Note: SLB is able to assign values between two variables: %newvar:%oldvar?).
[Arithmetic operations]
SLB language offers three basic arithmetic operations: +,-,*.
Adding declaration: ao (adding operation).
End of operation: ;ao
Subtraction declaration: so (subtraction operation).
End of operation: ;so
Multiply declaration: mo (multiply operation).
End of operation: ;mo
Usage:
------------
|::use_lb |
| ao |
| 5 |
| 6 |
| ;ao |
| |
------------
Textual output: 11 (5+6).
Arithmetic operations deal with commands in-line: they add/subtract/multiply numbers which follow.
Arithmetic operations are able to recognize variables:
------------
|::use_lb |
| %a:10? | -> Variable declaration.
| ao |
| 5 |
| ?a | -> Call of variable using key operator "?".
| ;ao |
| |
------------
Textual output: 15 (5+10).
[Shifting]
In SLB shifting means saving resul of arithmetic operations into variable.
Symbol of shifting: ->
This symbol must be placed right after end of arithmetic operation.
Usage:
-------------
| ::use_lb |
| %a:0? |
| mo |
| 5 |
| 2 |
| ;mo |
| ->?a | -> Shifting result of arithmetic operation.
-------------
Variable "a" gets value of 10 (5*2).
[Comparison]
Comparing numeric value in SLB begins with comparison declaration:
compare
...
;compare
SLB uses four basic operators: ++ (More than).
-- (Less than).
:: (Equals).
// (Modulo).
$$ (Square root leftover).
Usage:
-------------
| ::use_lb |
| cpr |
| 6 |
| ++ |
| 3 | -> "If 6 is more than 3, continue."
| -- |
| 7 | -> "If 3 is less than 7, continue."
| ;cpr |
-------------
If SLB evaluates condition as true, it will keep on reading following code.
If SLB evaluates condition as false, by default it keeps on reading too, but we can handle false evaluation.
In case of false evaluation, we can write into console own error message and terminate the session using >> symbol:
Usage:
-------------
| ::use_lb |
| cpr |
| 5 |
| ++ |
| 6 |--> 5 is in fact less than 6, so condition must be evaluated as false -----| |
+----->| >>error |<--Error message is sent to console----------------------------------------|
| | ;cpr |
| -------------
|
+---------------- Onfail operator MUST be called on last line of comparison.If comparison is evaluated as true, this statement is ignored.
Textual output: error .
[Functions]
In SLB, functions structure is simple and comprendious: a)Declaration of function (Symbol: f..)
b)Ending of function (Symbol: ..f)
Usage:
-----------------
| ::use_ln |
| f..myfunction | -> Declaration of function called "myfunction".
| msg abc | -> Functional code.
| ..f | -> Termination.
-----------------
Functions can be called using = symbol (e.g =myfunction).
They must be called on free line (outside of any operation, except of comparison).
Calling functions in comparison is an exception.They can be however called only as on-fail evaluation event.
|
|
|
v
--------------- ---------------
| ::use_ln | | ::use_ln |
| f..function | | f..function |
| msg Hello | | msg Hello |
| ..f | | ..f |
| cpr | OR | =function |
| 5 | ---------------
| ++ |
| 6 | (Called in free line).
| >>=function |
| ;cpr | Textual output: Hello.
---------------
(Called in comparison).
Textual output: Hello.
Note: Functions can be called inside of other functions too.
[Loop]
SLB offers to its users very basic structure of loops.
Loop consists of four basic parts: 1) Declaration.
2) Identifier of cycles amount.
3) Code.
4) Loop termination.
Usage:
--------------
| ::use_lb |
| go | -> Loop declaration.
| 3 | -> Cycles amount.
| ao |
| 5 |
| 1 |
| ;ao |
| @ | -> Termination.
--------------
Textual output: 6
6
6.
[rdln]
This command offers ability to read user-input and store it in variable.There are two ways to use this command:
------------ ------------
1. | ::use_lb | 2. | ::use_lb |
| rdln %a | | %a:6? |
| ao | | rdln ?a |
| ?a | | ao |
| ;ao | | ?a |
------------ | ;ao | Declaring new variable manually and changing it's value using rdln.
Declaring new variable using rdln. ------------
[Misc]
nomsg - is called inside of operation - result will not be sent into console as text.
Usage:
-------------
| ::use_lb |
| so |
| 5 |
| 6 |
| nomsg |
| ;so |
-------------
Textual output: NONE.
msg - is called outside of operation - sends text into console.
Usage:
-------------
| ::use_lb |
| msg hey |
-------------
Textual output: hey .
*/
public static String startclause = "::use_lb";
public static String addstart = "ao";
public static String addend = ";ao";
public static String substart = "so";
public static String subend = ";so";
public static String multstart = "mo";
public static String multend = ";mo";
public static String definer = "auto";
public static String key = "?";
public static String assigner = ":";
public static String shifter = "->";
public static String message = "msg";
public static String no_message = "nomsg";
public static String comparestart = "cpr";
public static String compareend = ";cpr";
public static String onfail = ">>";
public static String loopstart = "go";
public static String loopend = "@";
public static String funcstart = "f..";
public static String funcend = "..f";
public static String func_call = "=";
public static String secfile = "";
public static String read = "rdln";
public static Map<String, Integer> variables = new HashMap<String, Integer>();
public static Book lines = new Book(String.class,100);
public static Book names = new Book(String.class,10);
public static int comparations = 0;
public static int compstarts = 0;
public static int memory = 0;
public static int checker = 0;
private static boolean file_existance(String filename)
{
boolean exists = false;
File f = new File("C:\\SLBDIR" + "\\" + filename);
if(f.exists())exists = true;
return exists;
}
/*/
Core method- recognizing commands and cooperates with its sub-functions do determine
SLB syntax.
*/
public static void core(String mainfile)
{
secfile = "Fnc.txt";
if(SLB_COMPILER.file_existance(mainfile) && SLB_COMPILER.file_existance(secfile))
{
File f =new File("C:\\SLBDIR" + "\\" + mainfile);
File ff = new File("C:\\SLBDIR" + "\\" + secfile);
try{
BufferedReader br = new BufferedReader(new FileReader(f));
BufferedReader ack = new BufferedReader(new FileReader(f));
String line = null;
String cycles = "";
String external_function_query = "";
int index = 0;
int over = 0;
boolean jumpstart = false;
while ((line = br.readLine()) != null)
{
if(line.equals(""))
continue;
index = index + 1;
if(!line.equals(startclause) && index == 1)
SLB_COMPILER.throw_error("missing slb declaration.",true,line);
else
{
if(index > 1 && line.equals(addstart))
{
SLB_COMPILER.checkend(addstart,addend, f, line);
int add_result = 0;
boolean msg_gate = true;
while(!(line = br.readLine()).equals(addend))
{
if(line.equals(no_message)){msg_gate=false;continue;}
add_result = add_result + SLB_COMPILER.variabler(line);
}
if(msg_gate)
System.out.println(add_result);
memory = add_result;
}
if(index > 1 && line.equals(substart))
{
SLB_COMPILER.checkend(substart,subend, f, line);
int sub_result = 0;
int i = 0;
boolean msg_gate = true;
while(!(line = br.readLine()).equals(subend))
{
if(line.equals(no_message)){msg_gate = false;continue;}
i=i+1;
if(i == 1){sub_result = SLB_COMPILER.variabler(line);continue;}
sub_result = sub_result - SLB_COMPILER.variabler(line);
}
if(msg_gate)
System.out.println(sub_result);
memory = sub_result;
}
if(index > 1 && line.equals(multstart))
{
SLB_COMPILER.checkend(multstart,multend, f, line);
int mult_result = 0;
int i = 0;
boolean msg_gate = true;
while(!(line = br.readLine()).equals(multend))
{
if(line.equals(no_message)){msg_gate = false;continue;}
i=i+1;
if(i == 1){mult_result = SLB_COMPILER.variabler(line);continue;}
mult_result = mult_result * SLB_COMPILER.variabler(line);
}
if(msg_gate)
System.out.println(mult_result);
memory = mult_result;
}
if(index > 1 && line.length() > definer.length() && line.substring(0, definer.length()).equals(definer))
{
String varname = "";
String value = "";
value = value + line.substring(definer.length()+assigner.length()+1,line.length()-key.length());
if(!line.substring(line.length()-key.length(),line.length()).equals(key))
SLB_COMPILER.throw_error("missing endpoint.", true, line);
for(int c=0;c<=line.length()-(key.length()+assigner.length());c++)
{
if((c>=definer.length()))
{
if(line.substring(c,c+assigner.length()).equals(assigner))break;
varname = varname + line.substring(c, c+1);
}
}
try{
if(index > 1 && value.contains(definer))
{
if(variables.containsKey(value.substring(definer.length(),definer.length()+1)) && !variables.containsKey(varname))
{
variables.put(varname,SLB_COMPILER.variabler(key+value.substring(definer.length(),definer.length()+1)));
}
else
{
SLB_COMPILER.throw_error("right side variable not defined yet.",true,line);
}
}
else if(!value.contains(definer) && !variables.containsKey(varname))
variables.put(varname,Integer.parseInt(value));
else
{
SLB_COMPILER.throw_error("variable already defined.",true,line);
}
}
catch(NumberFormatException e){SLB_COMPILER.throw_error("wrong variable declaration.", true, line);}
}
if(index > 1 && line.length() >= message.length() && line.substring(0, message.length()).equals(message))
{
String value = "";
for(int u=0;u<=line.length()-1;u++)
{
if(u>3)
value = value + line.substring(u, u+1);
}
System.out.println(value);
}
if(index > 1 && line.length() > shifter.length() && line.contains(shifter))
{
if(line.substring(0, shifter.length()+key.length()).equals(shifter+key))
{
String value = "";
for(int g=shifter.length()+key.length()-1;g<=line.length()-1;g++)
{
value = value + line.substring(g, g+1);
}
if(variables.containsKey(value))
{
variables.replace(value, memory);
}
else
SLB_COMPILER.throw_error("variable not defined yet.",true,line);
}
else
{
SLB_COMPILER.throw_error("wrong shifter argument.",true,line);
}
}
if(index > 1 && line.equals(comparestart))
{
int values = 1;
int vo = 0;
int vt = 0;
boolean end = false;
String operator = "";
SLB_COMPILER.checkend(comparestart,compareend, f, line);
while(!(line = br.readLine()).equals(compareend))
{
if(line.substring(0,key.length()).equals(key) || strnum(line))
{
values = values + 1;
if(values%2==0)
{
vo = SLB_COMPILER.variabler(line);
if(values>2)
if(!SLB_COMPILER.operators(vt,vo,operator))
end = true;
}
else
{
vt = SLB_COMPILER.variabler(line);
if(!SLB_COMPILER.operators(vo,vt,operator))
end = true;
}
}
else
operator = line;
if(line.length() > onfail.length() && line.substring(0, onfail.length()).equals(onfail) && end)
{
if(line.length() > func_call.length() + onfail.length() && line.substring(onfail.length(), func_call.length()+onfail.length()).equals(func_call))
{
jumpstart = true;
external_function_query = line.substring(onfail.length(), line.length());
}
else
{
System.out.println(line.substring(onfail.length(), line.length()));
System.exit(0);
}
}
}
}
if(index > 1 && line.equals(loopstart))
{
br.mark(100);
cycles = br.readLine();
SLB_COMPILER.checkend(loopstart,loopend, f, line);
}
if(index > 1 && line.equals(loopend))
{
try
{
if(SLB_COMPILER.variabler(cycles)-1 == over){over=0;continue;}
over = over+1;
br.reset();
}catch(NumberFormatException e){SLB_COMPILER.throw_error("first line of loop must contain a number.",true,line);}
}
if(index > 1 && line.length() > funcstart.length() && line.substring(0, funcstart.length()).equals(funcstart) && mainfile == "SLB sheet.txt")
{
SLB_COMPILER.check_f_end(f,line);
if(lines.absorbs(line))SLB_COMPILER.throw_error("function already defined.", true, line);
lines.write(startclause);
lines.write(line);
while(!(line = br.readLine()).equals(funcend))
{
lines.write(line);
}
lines.write(line);
}
if(index > 1 && line.length() > func_call.length() && line.substring(0,func_call.length()).equals(func_call)||jumpstart)
{
if(jumpstart)
{
line = external_function_query;
jumpstart = false;
}
if(!lines.absorbs(funcstart+line.substring(func_call.length(), line.length())))
SLB_COMPILER.throw_error("function not defined.", true, line);
boolean stage = false;
FileWriter funcliner = new FileWriter(ff);
funcliner.write(lines.chainAt(1));
funcliner.write(System.getProperty("line.separator"));
for(int i=1;i<=lines.count();i++)
{
if(lines.chainAt(i).equals(funcstart+line.substring(func_call.length(), line.length())))stage = true;
if(!stage)
if(!lines.chainAt(i).equals(funcstart+line.substring(func_call.length(), line.length())))continue;
funcliner.write(lines.chainAt(i));
funcliner.write(System.getProperty("line.separator"));
if(lines.chainAt(i).equals(funcend))break;
}
funcliner.close();
BufferedReader fr = new BufferedReader(new FileReader(ff));
String ln = "";
while(!(ln = fr.readLine()).equals(funcstart + line.substring(func_call.length(), line.length()))){ln.length();}
SLB_COMPILER.core(secfile);
fr.close();
}
if(index > 1 && line.length() > read.length() && line.substring(0,read.length()).equals(read))
{
BufferedReader vl = new BufferedReader(new InputStreamReader(System.in));
String assoc = vl.readLine();
if(!strnum(assoc))SLB_COMPILER.throw_error("rdln argument must be number.", true, line);
if(line.substring(read.length()+1,read.length()+2).equals(definer))
{
variables.put(line.substring(read.length()+2, line.length()), Integer.parseInt(assoc));
}
if(line.substring(read.length()+1,read.length()+2).equals(key))
{
variables.replace(line.substring(read.length()+2, line.length()), Integer.parseInt(assoc));
}
}
}
}
ack.close();
br.close();
}
catch(IOException e){}
}
else
{
SLB_COMPILER.throw_error("core file not found.", true, "");
}
}
/*/
Method recognizing variables on-call by key (current: ?) and returning its value
into arithmetic operation.Based on HashMap fetching.
*/
public static int variabler(String ln)
{
try{
if(ln.equals(""))return 0;
String value = "";
if(ln.substring(0,key.length()).equals(key))
{
value=ln.replace(key, "");
if(variables.containsKey(value))return variables.get(value);
else{SLB_COMPILER.throw_error("variable not defined yet.",true,ln);}
}
else
return Integer.parseInt(ln);
}
catch(NumberFormatException e){SLB_COMPILER.throw_error("wrong number format.",true,ln);}
return 0;
}
/*/
Method recognizing operators and comparing two values in linear sequence.
*/
public static boolean operators(int valueone, int valuetwo, String operator)
{
boolean gate = false;
if(operator.equals("++"))
{
if(valueone > valuetwo)
gate=true;
else
gate=false;
}
else if(operator.equals("--"))
{
if(valueone < valuetwo)
gate = true;
else
gate = false;
}
else if(operator.equals("::"))
{
if(valueone == valuetwo)
gate = true;
else
gate = false;
}
else if(operator.equals("//"))
{
if(valueone%valuetwo == 0)
gate = true;
else
gate = false;
}
else if(operator.equals("$$"))
{
double value = valueone;
if(Math.sqrt(value)%1 == valuetwo)
gate = true;
else
gate = false;
}
else
SLB_COMPILER.throw_error("operation not supported.", true, operator);
return gate;
}
/*/
Method able to recognize if string has integer equivalent.
*/
public static boolean strnum(String text)
{
try
{
if(Integer.parseInt(text)/1 == Integer.parseInt(text))
return true;
else
return false;
}catch(NumberFormatException e){return false;}
}
/*/
Error handling method.
*/
public static void throw_error(String msg,boolean exit,String ln)
{
System.out.println("["+"Error- "+msg+"]");
System.out.println("["+ln+"]");
if(exit)System.exit(0);
else return;
}
/*/
Method deciding if code is well-written from operation-ending point.
*/
public static void checkend(String start,String end,File file,String ln)throws FileNotFoundException,IOException
{
BufferedReader r = new BufferedReader(new FileReader(file));
String spec_ln = "";
int starts = 0;
int ends = 0;
while((spec_ln = r.readLine()) != null)
{
if(spec_ln.equals(end))
ends = ends + 1;
if(spec_ln.equals(start))
starts = starts + 1;
}
r.close();
if(starts == ends)return;
SLB_COMPILER.throw_error("no possible ending of operation.", true, ln);
}
public static void check_f_end(File file,String ln)throws FileNotFoundException,IOException
{
BufferedReader r = new BufferedReader(new FileReader(file));
String spec_ln = "";
int starts = 0;
int ends = 0;
while((spec_ln = r.readLine()) != null)
{
if(spec_ln.length() > funcstart.length() && spec_ln.substring(0,funcstart.length()).equals(funcstart))
starts = starts + 1;
if(spec_ln.equals(funcend))
ends = ends + 1;
}
r.close();
if(starts == ends)return;
SLB_COMPILER.throw_error("no possible ending of operation.", true, ln);
}
public static void main(String args[])
{
core("SLB sheet.txt");
}
}
public class Book
{
public String[] str_storage;
private int[] int_storage;
private Class glob_cls;
public Book(Class<?> cls,int range)
{
if(cls == String.class){
glob_cls = cls;
str_storage = new String[range];
}
else if(cls == int.class){
glob_cls = cls;
int_storage = new int[range];
for(int i=0;i<=range-1;i++){
int_storage[i] = -Integer.MAX_VALUE;
}
}
}
public void add(int arg)
{
for(int i=0;i<=int_storage.length-1;i++)
{
if(int_storage[i] == -Integer.MAX_VALUE){
int_storage[i] = arg;
return;
}
}
}
public void write(String arg)
{
for(int i=0;i<=str_storage.length-1;i++)
{
if(str_storage[i] == null){
str_storage[i] = arg;
return;
}
}
}
public int count()
{
int index = 0;
if(glob_cls == String.class){
for(int i=0;i<=str_storage.length-1;i++)
{
if(str_storage[i] != null)
index = index + 1;
}
}
else if(glob_cls == int.class){
for(int i=0;i<=int_storage.length-1;i++)
{
if(int_storage[i] != -Integer.MAX_VALUE)
index = index + 1;
}
}
return index;
}
public String chainAt(int arg)
{
return str_storage[arg-1];
}
public int valueAt(int arg)
{
return int_storage[arg-1];
}
public boolean contains(int value)
{
for(int i=0;i<=int_storage.length-1;i++){
if(int_storage[i] == value)
return true;
}
return false;
}
public boolean absorbs(String value)
{
for(int i=0;i<=str_storage.length-1;i++){
if(str_storage[i] != null && str_storage[i].equals(value))
return true;
}
return false;
}
public static void main(String args[])
{
}
}
Comments