zkas: Add zkas code from zkas repo.

This commit is contained in:
parazyd
2021-12-19 16:59:32 +01:00
parent 3fb78520f0
commit 3511b8ff51
9 changed files with 685 additions and 0 deletions

293
zkas/Cargo.lock generated Normal file
View File

@@ -0,0 +1,293 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "colour"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a27e4532f26f510c24bb8477d963c0c3ef27e293c3b2c507cccb0536d493201a"
dependencies = [
"crossterm",
]
[[package]]
name = "crossterm"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c36c10130df424b2f3552fcc2ddcd9b28a27b1e54b358b45874f88d1ca6888c"
dependencies = [
"bitflags",
"crossterm_winapi",
"lazy_static",
"libc",
"mio",
"parking_lot",
"signal-hook",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0da8964ace4d3e4a044fd027919b2237000b24315a37c916f61809f1ff2140b9"
dependencies = [
"winapi",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]]
name = "lock_api"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "mio"
version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
dependencies = [
"libc",
"log",
"miow",
"ntapi",
"winapi",
]
[[package]]
name = "miow"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
"winapi",
]
[[package]]
name = "ntapi"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
dependencies = [
"winapi",
]
[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]]
name = "redox_syscall"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
dependencies = [
"bitflags",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "signal-hook"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
dependencies = [
"libc",
"mio",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [
"libc",
]
[[package]]
name = "smallvec"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "zkas"
version = "0.0.1"
dependencies = [
"anyhow",
"clap",
"colour",
]

13
zkas/Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "zkas"
version = "0.0.1"
homepage = "https://dark.fi"
authors = ["darkfi <dev@dark.fi>"]
repository = "https://github.com/darkrenaissance/darkfi"
license = "AGPL-3.0-only"
edition = "2021"
[dependencies]
anyhow = "1.0.49"
clap = "2.34.0"
colour = "0.6.0"

34
zkas/Makefile Normal file
View File

@@ -0,0 +1,34 @@
.POSIX:
# Cargo binary
CARGO = cargo
BINS = zkas
# Dependencies which should force the binaries to be rebuilt
BINDEPS = \
Cargo.toml \
$(shell find src -type f)
all: $(BINS)
$(BINS): $(BINDEPS)
$(CARGO) build --release --all-features --bin $@
cp -f target/release/$@ $@
test:
$(CARGO) test --release --all-features
fix:
$(CARGO) clippy --release --all-features --fix --allow-dirty
clippy:
$(CARGO) clippy --release --all-features
clean:
rm -f $(BINS)
distclean: clean
rm -rf target
.PHONY: all test fix clippy clean distclean

22
zkas/src/bin/zkas.rs Normal file
View File

@@ -0,0 +1,22 @@
use anyhow::Result;
use clap::clap_app;
use std::fs::read_to_string;
use zkas::lexer::lex;
fn main() -> Result<()> {
let args = clap_app!(zkas =>
(@arg INPUT: +required "ZK script to compile")
)
.get_matches();
let filename = args.value_of("INPUT").unwrap();
let source = read_to_string(filename)?;
let tokens = lex(filename, source.chars());
println!("{:#?}", tokens);
//let ast = parse(tokens);
Ok(())
}

73
zkas/src/error.rs Normal file
View File

@@ -0,0 +1,73 @@
use colour::{e_prnt_ln, e_red};
pub struct LexerError {
file: String,
lines: Vec<String>,
}
impl LexerError {
pub fn new(file: &str, lines: Vec<String>) -> Self {
LexerError { file: file.to_string(), lines }
}
pub fn invalid_token(&self, t: char, ln: usize, col: usize) {
let err_msg = format!("Invalid token `{}` on line {} (column {})\n", t, ln, col);
let dbg_msg = format!("{}:{}:{}: {}", self.file, ln, col, self.lines[ln - 1]);
let pad = dbg_msg.split(": ").next().unwrap().len() + col + 2;
let caret = format!("{:width$}^", "", width = pad);
let msg = format!("{}\n{}\n{}", err_msg, dbg_msg, caret);
LexerError::lexer_error(&msg);
}
pub fn invalid_string(&self, s: &str, ln: usize, col: usize) {
let err_msg = format!("Invalid ending in string `{}` on line {} (column {})", s, ln, col);
let dbg_msg = format!("{}:{}:{}: {}", self.file, ln, col, self.lines[ln - 1]);
let pad = dbg_msg.split(": ").next().unwrap().len() + col + 2;
let caret = format!("{:width$}^", "", width = pad);
let msg = format!("{}\n{}\n{}", err_msg, dbg_msg, caret);
LexerError::lexer_error(&msg);
}
pub fn invalid_symbol(&self, s: &str, ln: usize, col: usize) {
let err_msg = format!("Illegal char `{}` for symbol on line {} (column {})", s, ln, col);
let dbg_msg = format!("{}:{}:{}: {}", self.file, ln, col, self.lines[ln - 1]);
let pad = dbg_msg.split(": ").next().unwrap().len() + col + 2;
let caret = format!("{:width$}^", "", width = pad);
let msg = format!("{}\n{}\n{}", err_msg, dbg_msg, caret);
LexerError::lexer_error(&msg);
}
fn lexer_error(msg: &str) {
e_red!("Lexer error: ");
e_prnt_ln!("{}", msg);
std::process::exit(1);
}
}
pub struct ParserError {
file: String,
lines: Vec<String>,
}
impl ParserError {
pub fn new(file: &str, lines: Vec<String>) -> Self {
ParserError { file: file.to_string(), lines }
}
pub fn invalid_section_declaration(&self, s: &str, m: &str, ln: usize, col: usize) {
let err_msg =
format!("Invalid `{}` section declaration on line {} (column {})", s, ln, col);
let err_msg = format!("{}\n{}", err_msg, m);
let dbg_msg = format!("{}:{}:{}: {}", self.file, ln, col, self.lines[ln - 1]);
let pad = dbg_msg.split(": ").next().unwrap().len() + col + 2;
let caret = format!("{:width$}^", "", width = pad);
let msg = format!("{}\n{}\n{}", err_msg, dbg_msg, caret);
ParserError::parser_error(&msg);
}
fn parser_error(msg: &str) {
e_red!("Parser error: ");
e_prnt_ln!("{}", msg);
std::process::exit(1);
}
}

208
zkas/src/lexer.rs Normal file
View File

@@ -0,0 +1,208 @@
use std::str::Chars;
use crate::error::LexerError;
#[derive(Clone, PartialEq, Debug)]
pub enum TokenType {
Symbol,
String,
LeftBrace,
RightBrace,
LeftParen,
RightParen,
Comma,
Semicolon,
Colon,
Assign,
}
const SPECIAL_CHARS: [char; 7] = ['{', '}', '(', ')', ',', ';', '='];
#[derive(Clone, Debug)]
pub struct Token {
pub token: String,
pub token_type: TokenType,
pub line: usize,
pub column: usize,
}
impl Token {
fn new(token: String, token_type: TokenType, line: usize, column: usize) -> Self {
Token { token, token_type, line, column }
}
}
pub fn lex(filename: &str, source: Chars) -> Vec<Token> {
// For nice error reporting, we'll load everything into a string vector
// so we have references to lines.
let lines: Vec<String> = source.as_str().lines().map(|x| x.to_string()).collect();
let lexer_error = LexerError::new(filename, lines);
let mut tokens = vec![];
let mut lineno = 1;
let mut column = 0;
// We use these as a buffer to keep strings/symbols.
let mut strbuf = String::new();
let mut symbuf = String::new();
// We use these to keep state when iterating
let mut in_comment = false;
let mut in_string = false;
let mut in_symbol = false;
#[allow(clippy::explicit_counter_loop)]
for c in source {
column += 1;
if c == '\n' {
if in_symbol {
in_symbol = false;
tokens.push(Token::new(
symbuf.clone(),
TokenType::Symbol,
lineno,
column - symbuf.len(),
));
symbuf = String::new();
}
if in_string {
// TODO: Allow newlines in strings?
lexer_error.invalid_string(&strbuf, lineno, column);
}
in_comment = false;
lineno += 1;
column = 0;
continue
}
if c == '#' || in_comment {
if in_symbol {
in_symbol = false;
tokens.push(Token::new(
symbuf.clone(),
TokenType::Symbol,
lineno,
column - symbuf.len(),
));
symbuf = String::new();
}
if in_string {
strbuf.push(c);
continue
}
in_comment = true;
continue
}
if c.is_whitespace() {
if in_symbol {
in_symbol = false;
tokens.push(Token::new(
symbuf.clone(),
TokenType::Symbol,
lineno,
column - symbuf.len(),
));
symbuf = String::new();
}
continue
}
if !in_string && is_letter(c) {
in_symbol = true;
symbuf.push(c);
continue
}
if in_string && is_letter(c) {
strbuf.push(c);
continue
}
if c == '"' && !in_string {
if in_symbol {
lexer_error.invalid_symbol(&symbuf, lineno, column);
}
in_string = true;
continue
}
if c == '"' && in_string {
in_string = false;
tokens.push(Token::new(
strbuf.clone(),
TokenType::String,
lineno,
column - strbuf.len(),
));
strbuf = String::new();
continue
}
if SPECIAL_CHARS.contains(&c) {
if in_symbol {
in_symbol = false;
tokens.push(Token::new(
symbuf.clone(),
TokenType::Symbol,
lineno,
column - symbuf.len(),
));
symbuf = String::new();
}
match c {
'{' => {
tokens.push(Token::new("{".to_string(), TokenType::LeftBrace, lineno, column));
continue
}
'}' => {
tokens.push(Token::new("}".to_string(), TokenType::RightBrace, lineno, column));
continue
}
'(' => {
tokens.push(Token::new("(".to_string(), TokenType::LeftParen, lineno, column));
continue
}
')' => {
tokens.push(Token::new(")".to_string(), TokenType::RightParen, lineno, column));
continue
}
',' => {
tokens.push(Token::new(",".to_string(), TokenType::Comma, lineno, column));
continue
}
';' => {
tokens.push(Token::new(";".to_string(), TokenType::Semicolon, lineno, column));
continue
}
'=' => {
tokens.push(Token::new("=".to_string(), TokenType::Assign, lineno, column));
continue
}
_ => lexer_error.invalid_token(c, lineno, column - 1),
}
continue
}
lexer_error.invalid_token(c, lineno, column - 1);
}
tokens
}
fn is_letter(ch: char) -> bool {
('a'..='z').contains(&ch) || ('A'..='Z').contains(&ch) || ch == '_'
}
/*
fn is_digit(ch: char) -> bool {
('0'..'9').contains(&ch)
}
*/

3
zkas/src/lib.rs Normal file
View File

@@ -0,0 +1,3 @@
pub mod error;
pub mod lexer;
pub mod parser;

11
zkas/src/opcode.rs Normal file
View File

@@ -0,0 +1,11 @@
pub enum OpCode {
EcAdd = 0x00,
EcMul = 0x01,
EcMulShort = 0x02,
EcGetX = 0x03,
EcGetY = 0x04,
PoseidonHash = 0x10,
ConstrainInstance = 0xf0,
}

28
zkas/src/parser.rs Normal file
View File

@@ -0,0 +1,28 @@
use std::str::Chars;
use crate::{
error::ParserError,
lexer::{Token, TokenType},
};
pub fn parse(filename: &str, source: Chars, tokens: Vec<Token>) {
// For nice error reporting, we'll load everything into a string vector
// so we have references to lines.
let lines: Vec<String> = source.as_str().lines().map(|x| x.to_string()).collect();
let parser_error = ParserError::new(filename, lines);
// We use these to keep state when iterating
let mut declaring_constant = false;
let mut declaring_contract = false;
let mut declaring_circuit = false;
let mut iter = tokens.iter();
while let Some(t) = iter.next() {
// Start by declaring a section
if !declaring_constant && !declaring_contract && !declaring_circuit {
if t.token_type != TokenType::Symbol {
println!("FOO");
}
}
}
}