Skip to content
This repository has been archived by the owner on Jul 16, 2023. It is now read-only.

✨ v1.4.2 #19

Merged
merged 10 commits into from
Nov 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified build/UFB.jar
Binary file not shown.
Binary file modified build/UFB/Command$1.class
Binary file not shown.
Binary file removed build/UFB/Command$2.class
Binary file not shown.
Binary file modified build/UFB/Command.class
Binary file not shown.
Binary file modified build/UFB/FlagManager.class
Binary file not shown.
Binary file added build/UFB/GenericCommand.class
Binary file not shown.
Binary file added build/UFB/JumpCommand.class
Binary file not shown.
Binary file added build/UFB/MathCommand.class
Binary file not shown.
Binary file added build/UFB/NeedsArgLengthCommand.class
Binary file not shown.
Binary file added build/UFB/NeedsOneMemCommand.class
Binary file not shown.
Binary file added build/UFB/NopCommand.class
Binary file not shown.
Binary file removed build/UFB/Optimizer$1.class
Binary file not shown.
Binary file removed build/UFB/Optimizer.class
Binary file not shown.
Binary file added build/UFB/PrintCommand.class
Binary file not shown.
Binary file modified build/UFB/Runner$1.class
Binary file not shown.
Binary file modified build/UFB/Runner.class
Binary file not shown.
Binary file added build/UFB/TrimCommand.class
Binary file not shown.
Binary file removed build/UFB/UFB$1.class
Binary file not shown.
Binary file removed build/UFB/UFB$2.class
Binary file not shown.
Binary file modified build/UFB/UFB.class
Binary file not shown.
Binary file modified build/UFB/UFBC$2.class
Binary file not shown.
Binary file modified build/UFB/UFBC.class
Binary file not shown.
Binary file added build/UFB/WvarCommand.class
Binary file not shown.
1 change: 1 addition & 0 deletions build/build.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/sh
cd UFB
rm *
echo "javac ../../src/UFB/*.java -d . -Xdiags:verbose"
javac ../../src/UFB/*.java -d . -Xdiags:verbose
echo "jar --create --file=../UFB.jar --main-class=UFB *.class"
Expand Down
197 changes: 59 additions & 138 deletions src/UFB/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.util.concurrent.ExecutorService;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

class Command{
final ArrayList<Integer> compiled=new ArrayList<>();
Expand All @@ -35,7 +34,6 @@ class Command{
final Pattern jumps;
final Pattern maths;
final Pattern pwvar;
final Pattern unicode;
final String[] line;
final String[] realLine;
boolean cancelOptimization=false;
Expand All @@ -53,7 +51,7 @@ public String getErrors(){
}

private Command(final String[] line, final String[] realLine, final ExecutorService executor,
final Pattern jumps, final Pattern maths, final Pattern pwvar, final Pattern unicode,
final Pattern jumps, final Pattern maths, final Pattern pwvar,
final HashMap<String, Integer> binaryMap){
this.line=line;
this.realLine=realLine;
Expand All @@ -62,173 +60,96 @@ private Command(final String[] line, final String[] realLine, final ExecutorServ
this.jumps=jumps;
this.maths=maths;
this.pwvar=pwvar;
this.unicode=unicode;
this.line[0]=this.line[0].toLowerCase();
}
private void compile(){
executor.execute(new Runnable(){
public void run(){
checkCases();
if(errors.length()==0){
final int index=binaryMap.get(line[0]);
compiled.add(index);
if(index>9&&index<14){
final String[] args=new String[line.length-2];
System.arraycopy(line, 1, args, 0, args.length);
for(final String s:args)
compiled.add(toIntAbsolute(s));
final int lineNo=toIntAbsolute(line[line.length-1]);
final String bin=UFBC.manPadding(Integer.toBinaryString(lineNo), 16);
final String bin1=bin.substring(0, 8);
if(!bin1.contains("0"))
compiled.add(0);
else
compiled.add(Integer.parseInt(bin1, 2));
compiled.add(Integer.parseInt(bin.substring(8), 2));
}else{
final String[] args=new String[line.length-1];
System.arraycopy(line, 1, args, 0, args.length);
if(index==0||index==14)
compiled.add(args.length);
for(final String s:args)
compiled.add(toIntAbsolute(s));
}
try{
final GenericCommand com=getCommand(binaryMap.get(line[0]));
errors.append(com.getErrors());
for(final int i:com.getCompiled())
compiled.add(i);
}catch(final NullPointerException e){
errors.append(formatError(
line, "Command", line[0],
"Does Not Exist"
));
}
}
});
}
private void checkCases(){
boolean isCommand=true;
if(line[0].equals("trim"))
checkLength(line, 3);
else if(line[0].equals("nvar")){
if(!checkLength(line, 2))
checkIfMemSafe(line, line[1]);
}else if(line[0].equals("read")){
if(!checkLength(line, 2)){
checkIfMemSafe(line, line[1]);
private GenericCommand getCommand(final int comInd){
switch(comInd){
case 0:
return new WvarCommand(line, realLine);
case 2:
return new TrimCommand(line, realLine);
case 3: case 4: case 5: case 6: case 7: case 8:
return new MathCommand(comInd, line, realLine);
case 9:
return new NopCommand(line, realLine);
case 10: case 11: case 12: case 13:
return new JumpCommand(comInd, line, realLine);
case 14:
return new PrintCommand(line, realLine);
case 15:
cancelOptimization=true;
}
}else if(jumps.matcher(line[0]).matches()){
if(!checkLength(line, 4))
for(byte i=1;i<3;i++)checkIfMem(line, line[i]);
}else if(maths.matcher(line[0]).matches()){
if(!checkLength(line, 3)){
checkIfMemSafe(line, line[1]);
for(byte i=1;i<3;i++)checkIfMem(line, line[i]);
}
}else if(pwvar.matcher(line[0]).matches()){
if(line.length>256)
error(
realLine, "Command", line[0],
"Has Too Many Arguments",
lineGen(line)
);
else{
if(line[0].startsWith("w"))
checkIfMemSafe(line, line[1]);
for(short i=2;i<line.length;i++)
checkIfMem(line, line[i]);
}
}else if(line[0].equals("nop")) // One day I'll regret this.
checkLength(line, 1);
else{
error(
line, "Command", line[0],
"Does Not Exist"
);
isCommand=false;
case 1:
return new NeedsOneMemCommand(comInd, line, realLine);
default:
return null;
}
if(!line[0].equalsIgnoreCase("nop")&&isCommand)
checkIfMem(line, line[1]);
}
private int toIntAbsolute(final String s){
return toIntAbsolute(s.toCharArray());
}
private int toIntAbsolute(final char[] arr){
public static int toIntAbsolute(final String s){
// BeCoz Integer#parseInt() is slow and try-catch is expensive.
int result=0;
for(final char c:arr){
for(final char c:s.toCharArray()){
result+=c-48;
result*=10;
}
return result/10;
}
private void checkIfMem(final String[] line, final String s){
try{
if(Long.parseLong(s)>255)
error(
line, "Memory Index", s,
"Is Larger Than 255 And Will Not Point To Memory"
);
}catch(final Exception e){
error(
line, "Memory Index Expected Instead Of", s,
"Should Be Replaced With A Memory Index"
);
}
}
private void checkIfMemSafe(final String[] line, final String s){
try{
if(Long.parseLong(s)<38)
error(
line, "Memory Index", s,
"Endangers A Read-Only Memory Index"
);
}catch(final Exception e){
error(
line, "Memory Index Expected Instead Of", s,
"Should Be Replaced With A Memory Index"
);
}
}
// false if error is not thrown. Misleading eh?
private boolean checkLength(final String[] line, final int length){
if(line.length!=length){
final String num=(length<1)?"Zero":(length==1)?"One":(length==2)?"Two":"Three";
error(
line, "Command", line[0],
String.format("Needs No Less And No More Than %s Argument To Work", num)
);
return true;
}
return false;
}
private String lineGen(final String[]line){
}
public static String lineGen(final String[]line){
return Arrays.toString(line).substring(1).replace(", ", " ").replace("]", "\n\n");
}
private void error(final String[] line, final String... in){
public static String formatError(final String[] line, final String... in){
if(in.length<4)
errors.append("Error: |\n")
return new StringBuilder("Error: |\n")
.append(String.format(" %s: |\n", in[0]))
.append(String.format(" \"%s\" %s: |\n", in[1], in[2]))
.append(String.format(" %s", lineGen(line)));
.append(String.format(" %s", lineGen(line))).toString();
else
errors.append("Error: |\n")
return new StringBuilder("Error: |\n")
.append(String.format(" %s: |\n", in[0]))
.append(String.format(" \"%s\" %s: |\n", in[1], in[2]))
.append(String.format(" %s", convertUnicode(lineGen(line).replace("\n\n", "\n"))))
.append(String.format(" %s: |\n", "Which Is When Converted"))
.append(String.format(" %s", in[3]));
}
private String convertUnicode(final String in){
if(in.length()<2)return in;
String line=in;
try{
for(final Matcher m=unicode.matcher(line);m.find();m.reset(line)){
line=new StringBuilder(line.substring(0, m.start()))
.append((char)toIntAbsolute(
line.substring(m.start()+2, m.end()).toCharArray()
))
.append(line.substring(m.end())).toString();
.append(String.format(" %s", in[3])).toString();
}
public static String convertUnicode(final String in){
if(in.length()<6)return in;
String temp=in;
// Regex slow ._.
for(int i=0;i<temp.length()-6;i++){
if(temp.substring(i, i+2).toLowerCase().equals("uu")){
boolean confirmed=true;
for(int i2=i+2;i2<6;i2++)
if(!Runner.isDigit(temp.charAt(i2)))confirmed=false;
if(confirmed)
temp=new StringBuilder(temp.substring(0, i))
.append((char)toIntAbsolute(
temp.substring(i+2, i+6)
))
.append(temp.substring(i+6)).toString();
}
}catch(final Exception e){}
return line;
}
return temp;
}
public static Command create(final String[] line, final String[] realLine, final ExecutorService executor,
final Pattern jumps, final Pattern maths, final Pattern pwvar, final Pattern unicode,
final Pattern jumps, final Pattern maths, final Pattern pwvar,
final HashMap<String, Integer> binaryMap){
final Command com=new Command(line, realLine, executor, jumps, maths, pwvar, unicode, binaryMap);
final Command com=new Command(line, realLine, executor, jumps, maths, pwvar, binaryMap);
com.compile();
return com;
}
Expand Down
10 changes: 10 additions & 0 deletions src/UFB/FlagManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*
**/

import java.io.File;

import java.util.Arrays;

import java.util.regex.Pattern;
Expand Down Expand Up @@ -78,6 +80,14 @@ else if(arg.startsWith("--")){
);
}
file=fileName;
if(fileName.length()==0){
System.out.println("No file input found, terminating.");
System.exit(1);
}
if(!new File(fileName).exists()){
System.out.println("File Provided Does Not Exist...\nTerminating...");
System.exit(1);
}
}
public boolean isFlagActivated(final char c){
final char[] array=flagString.substring(1).toCharArray();
Expand Down
26 changes: 26 additions & 0 deletions src/UFB/GenericCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
*
* Unsafe Four Bit is a compiled-interpreted, dynamically-typed programming language.
* Copyright (C) 2022 JumperBot_
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
**/

interface GenericCommand{
public void compile(final String[] line);
public int[] getCompiled();
public void checkCases(final String[] line, final String[] realLine);
public String getErrors();
}
81 changes: 81 additions & 0 deletions src/UFB/JumpCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
*
* Unsafe Four Bit is a compiled-interpreted, dynamically-typed programming language.
* Copyright (C) 2022 JumperBot_
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
**/

class JumpCommand implements GenericCommand{
final int comInd;
final int[] compiled;
final StringBuilder errors=new StringBuilder();
public JumpCommand(final int comInd, final String[] line, final String[] realLine){
this.comInd=comInd;
compiled=new int[line.length+1];
checkCases(line, realLine);
compile(line);
}
@Override
public void compile(final String[] line){
compiled[0]=comInd;
for(int i=1;i<line.length;i++)
compiled[i]=Command.toIntAbsolute(line[i]);
final short lineNum=(short)Command.toIntAbsolute(line[line.length-1]);
compiled[compiled.length-2]=lineNum>>>8;
compiled[compiled.length-1]=lineNum<<8>>>8;
}
@Override
public int[] getCompiled(){
return compiled;
}
@Override
public void checkCases(final String[] line, final String[] realLine){
if(line.length!=4)
errors.append(Command.formatError(
line, "Command", line[0],
"Needs No Less And No More Than Three Arguments To Work"
));
for(int i=1;i<line.length-1;i++)
if(Long.parseLong(line[i])>255)
try{
errors.append(Command.formatError(
line, "Memory Index", line[i],
"Is Larger Than 255 And Will Not Point To Memory"
));
}catch(final Exception e){
errors.append(Command.formatError(
line, "Memory Index Expected Instead Of", line[i],
"Should Be Replaced With A Memory Index"
));
}
if(Long.parseLong(line[line.length-1])>32767)
try{
errors.append(Command.formatError(
line, "Command Number", line[line.length-1],
"Is Larger Than 32767 And Will Not Point Accurately"
));
}catch(final Exception e){
errors.append(Command.formatError(
line, "Command Number Expected Instead Of", line[line.length-1],
"Should Be Replaced With A Command Number"
));
}
}
@Override
public String getErrors(){
return errors.toString();
}
}
Loading