Rewrite to Java, add Scanner, TokenTypes, and Main class

This commit is contained in:
Garrett Dickinson 2022-06-11 16:43:52 -05:00
parent 8c05ed5835
commit 449ce575a7
14 changed files with 147 additions and 106 deletions

View File

@ -1,2 +1,6 @@
# CobaltScript # Cobalt
A small programming language designed for general purpose scripting and for learning interpreter design Cobalt is a small programming language designed for general purpose and systems level scripting. This project follows very closely to the curriculum from [Crafting Interpreters](http://craftinginterpreters.com/) by Robert Nystrom, and is intended to be a pet project for myself to learn programming language design and interpreter design concepts.
Currently, Cobalt follows the same grammer and design structure as [Lox](https://github.com/munificent/craftinginterpreters), the language featured in Nystrom's book. However, I eventually plan to mutate Cobalt from these design patterns and create a unique syntax and structure once I have reached a high enough proficiency.
This project is a **work in progress**, so some things might be a bit broken. YMMV :)

68
cobalt/Cobalt.java Normal file
View File

@ -0,0 +1,68 @@
package cobalt;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
public class Cobalt {
static boolean hadError = false;
public static void main(String[] args) throws IOException {
if (args.length > 1) {
System.out.println("Usage: cobalt [script]");
System.exit(64);
} else if (args.length == 1) {
//runFile(args[0]);
} else {
//runPrompt()
}
}
private static void runFile(String path) throws IOException {
byte[] bytes = Files.readAllBytes(Paths.get(path));
run(new String(bytes, Charset.defaultCharset()));
if (hadError) System.exit(65);
}
private static void runPrompt() throws IOException {
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
for (;;) {
System.out.print("> ");
String line = reader.readLine();
if (line == null) break;
run(line);
hadError = false;
}
}
private static void run(String source) {
// Wont compile since we don't use the standard Java Scanner,
// gets implemented further in the textbook
Scanner scanner = new Scanner(source);
// Same situation for Token type
List<Token> tokens = scanner.scanTokens();
for (Token token : tokens) {
System.out.println(token);
}
}
static void error(int line, String message) {
report(line, "", message);
}
private static void report(int line, String where, String message) {
System.err.println(
"[line " + line + "] Error" + where + ": " + message
);
hadError = true;
}
}

34
cobalt/Scanner.java Normal file
View File

@ -0,0 +1,34 @@
package cobalt;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static cobalt.TokenType.*;
class Scanner {
private final String source;
private final List<Token> tokens = new ArrayList<>();
private int start = 0;
private int current = 0;
private int line = 0;
Scanner(String source) {
this.source = source;
}
List<Token> scanTokens() {
while (!isAtEnd()) {
start = current;
scanTokens();
}
tokens.add(new Token(EOF, "", null, line));
return tokens;
}
private boolean isAtEnd() {
return current >= source.length();
}
}

19
cobalt/Token.java Normal file
View File

@ -0,0 +1,19 @@
package cobalt;
class Token {
final TokenType type;
final String lexeme;
final Object literal;
final int line;
Token(TokenType type, String lexeme, Object literal, int line) {
this.type = type;
this.lexeme = lexeme;
this.literal = literal;
this.line = line;
}
public String toString() {
return type + " " + lexeme + " " + literal;
}
}

20
cobalt/TokenType.java Normal file
View File

@ -0,0 +1,20 @@
package cobalt;
enum TokenType {
// Single character tokens.
LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE,
COMMA, DOT, MINUS, PLUS, SEMICOLON, SLASH, STAR,
// One or two character tokens.
BANG, BANG_EQUAL, EQUAL, EQUAL_EQUAL,
GREATER, GREATER_EQUAL, LESS, LESS_EQUAL,
// Literals
IDENTIFIER, STRING, NUMBER,
// Keywords
AND, CLASS, ELSE, FALSE, FUN, FOR, IF, NIL, OR,
PRINT, RETURN, SUPER, THIS, TRUE, VAR, WHILE,
EOF
}

View File

@ -1,14 +0,0 @@
#include <iostream>
#ifndef LEXER_H
#define LEXER_H
class Lexer
{
private:
std::string extension = ".prog";
public:
Lexer(std::string &file_name);
};
#endif

View File

@ -1,14 +0,0 @@
#include <iostream>
#ifndef PARSER_H
#define PARSER_H
class Parser
{
private:
public:
Parser(std::string input_file);
};
#endif

View File

View File

@ -1,20 +0,0 @@
#OBJS specifies which files to compile as part of the project
OBJS = $(wildcard src/*.cpp)
#CC specifies which compiler we're using
CC = g++
#COMPILER_FLAGS specifies the additional compilation options we're using
# -w suppresses all warnings
COMPILER_FLAGS = -w
#LINKER_FLAGS specifies the libraries we're linking against
LINKER_FLAGS =
#OBJ_NAME specifies the name of our exectuable
OBJ_NAME = cobalt
#This is the target that compiles our executable
all : $(OBJS)
$(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OBJ_NAME)

View File

@ -1,3 +0,0 @@
hello world, this is a lexer test
hello world
Kanye's new name is Ye

View File

@ -1,30 +0,0 @@
#include <stdio.h>
#include <iostream>
#include <fstream>
#include "../include/lexer.h"
char c;
FILE* input_file;
Lexer::Lexer(std::string &file_name) {
input_file = fopen(file_name.c_str(),"r");
if(input_file == nullptr) {
std::cout << "[Error] Script " << input_file << " could not be read\n";
exit(1);
}
c = getc(input_file);
if (c == EOF) {
//do something related to eof here?
fclose(input_file);
}
}
char nextChar() {
if (c != EOF) {
c = getc(input_file);
} else {
c = EOF;
}
return c;
}

View File

@ -1,15 +0,0 @@
#include <stdio.h>
#include <iostream>
#include <vector>
#include "../include/lexer.h"
int main(int argc, char *argv[]) {
if (argc > 1) {
std::string file_name(argv[1]);
Lexer lex(file_name);
} else {
std::cout << "[Error] No input file provided\n";
}
return 0;
}

View File

@ -1,8 +0,0 @@
#include <stdio.h>
#include <iostream>
#include "../include/parser.h"
Parser::Parser(std::string input_file) {
}

View File