function passing

This commit is contained in:
Masato Imai
2022-07-22 10:22:38 +09:00
parent 660ed217be
commit 9eb9176a60
11 changed files with 171 additions and 122 deletions

View File

@ -4,6 +4,17 @@ fn add(a: num, b: num) {
return a + b;
}
#[server(ip = "localhost:8080")]
fn mul(a: num, b: num) {
return a * b;
}
fn main() {
println(add(1, 2));
println(mul(2, 2));
let i: num;
for (i = 0; i < 2000; i += 1) {
println(mul(i, i));
}
}

View File

@ -1,7 +1,6 @@
use bigdecimal::{num_bigint::BigInt, Zero, One};
use bigdecimal::{num_bigint::BigInt, One, Zero};
use primitive_types::U512;
use super::finite_field::FiniteFieldElement;
use bigdecimal::Num;
pub fn plus_mod(a: BigInt, m: BigInt) -> BigInt {
@ -20,7 +19,7 @@ pub fn abs(a: BigInt, p: BigInt) -> BigInt {
if a >= BigInt::zero() {
a % p
} else {
(p.clone()-(-a)%p.clone())%p
(p.clone() - (-a) % p.clone()) % p
}
}
@ -44,7 +43,7 @@ pub fn random_n_q(p: BigInt) -> BigInt {
let mut i = BigInt::one();
let k = (p.clone() - BigInt::one()) >> 1i32;
while i < p {
if bigint_to_u512(pow_mod(i.clone(),k.clone(),p.clone())) != U512::one() {
if bigint_to_u512(pow_mod(i.clone(), k.clone(), p.clone())) != U512::one() {
break;
}
i += BigInt::one();
@ -65,12 +64,20 @@ pub fn mod_sqrt(a: BigInt, p: BigInt) -> BigInt {
while (x.clone() & BigInt::one()) != BigInt::one() {
x = x >> 1u8;
y = y >> 1u8;
if abs(pow_mod(a.clone(), x.clone(), p.clone()) * pow_mod(b.clone(), y.clone(), p.clone()), p.clone()) != BigInt::one() {
if abs(
pow_mod(a.clone(), x.clone(), p.clone()) * pow_mod(b.clone(), y.clone(), p.clone()),
p.clone(),
) != BigInt::one()
{
y += r.clone();
}
}
abs(pow_mod(a.clone(), (x.clone() + BigInt::one()) >> 1u8, p.clone()) * pow_mod(b.clone(), y.clone() >> 1u8, p.clone()), p.clone())
abs(
pow_mod(a.clone(), (x.clone() + BigInt::one()) >> 1u8, p.clone())
* pow_mod(b.clone(), y.clone() >> 1u8, p.clone()),
p.clone(),
)
}
pub fn mod_inv(a: BigInt, m: BigInt) -> BigInt {

View File

@ -1,4 +1,7 @@
use std::{ops::{Add, Mul, Neg}, fmt::Display};
use std::{
fmt::Display,
ops::{Add, Mul, Neg},
};
use primitive_types::U512;
@ -7,12 +10,17 @@ use crate::common::finite_field::FiniteFieldElement;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct EllipticCurve {
pub a: FiniteFieldElement,
pub b: FiniteFieldElement
pub b: FiniteFieldElement,
}
impl EllipticCurve {
pub fn point(self, x: FiniteFieldElement, y: FiniteFieldElement) -> EllipticCurvePoint {
EllipticCurvePoint::Point { x, y, a: self.a, b: self.b }
EllipticCurvePoint::Point {
x,
y,
a: self.a,
b: self.b,
}
}
}
@ -22,13 +30,12 @@ pub enum EllipticCurvePoint {
x: FiniteFieldElement,
y: FiniteFieldElement,
a: FiniteFieldElement,
b: FiniteFieldElement
b: FiniteFieldElement,
},
Infinity
Infinity,
}
impl EllipticCurvePoint {
pub fn exp(&self, k: U512) -> Self {
if k == U512::zero() {
return Self::Infinity;
@ -56,35 +63,47 @@ impl EllipticCurvePoint {
}
}
pub fn extract(&self) -> (FiniteFieldElement, FiniteFieldElement, FiniteFieldElement, FiniteFieldElement) {
pub fn extract(
&self,
) -> (
FiniteFieldElement,
FiniteFieldElement,
FiniteFieldElement,
FiniteFieldElement,
) {
match self {
EllipticCurvePoint::Point { x, y, a, b } => (*x,*y,*a,*b),
_ => panic!("inifinity")
EllipticCurvePoint::Point { x, y, a, b } => (*x, *y, *a, *b),
_ => panic!("inifinity"),
}
}
pub fn lambda(p: EllipticCurvePoint, q: EllipticCurvePoint) -> FiniteFieldElement {
let (x1, y1) = match p {
EllipticCurvePoint::Point { x, y, .. } => (x,y),
_ => panic!("P is inifinity.")
EllipticCurvePoint::Point { x, y, .. } => (x, y),
_ => panic!("P is inifinity."),
};
let (x2, y2) = match q {
EllipticCurvePoint::Point { x, y, .. } => (x,y),
_ => panic!("Q is inifinity.")
EllipticCurvePoint::Point { x, y, .. } => (x, y),
_ => panic!("Q is inifinity."),
};
(y2 - y1) / (x2 - x1)
}
pub fn l(g: EllipticCurvePoint, h: EllipticCurvePoint, var: EllipticCurvePoint) -> FiniteFieldElement {
pub fn l(
g: EllipticCurvePoint,
h: EllipticCurvePoint,
var: EllipticCurvePoint,
) -> FiniteFieldElement {
//println!("L g: {}, h: {}, var: {}", g, h, var);
let (gx, gy, a, _) = g.extract();
let (hx, hy, _, _) = h.extract();
let (varx, vary, _, _) = var.extract();
let v = if g == h {
(FiniteFieldElement::new(U512::from(3u8), gx.p) * gx * gx + a) * (FiniteFieldElement::new(U512::from(2u8), gx.p) * gy).inverse()
(FiniteFieldElement::new(U512::from(3u8), gx.p) * gx * gx + a)
* (FiniteFieldElement::new(U512::from(2u8), gx.p) * gy).inverse()
} else {
(hy - gy) * (hx - gx).inverse()
};
@ -100,10 +119,14 @@ impl EllipticCurvePoint {
vx - rx
}
pub fn g(p: EllipticCurvePoint, q: EllipticCurvePoint, v: EllipticCurvePoint) -> FiniteFieldElement {
pub fn g(
p: EllipticCurvePoint,
q: EllipticCurvePoint,
v: EllipticCurvePoint,
) -> FiniteFieldElement {
let (px, py, _, _) = p.extract();
let (qx, qy, _, _) = q.extract();
let (vx, vy, _, _) = v.extract();
let (vx, _, _, _) = v.extract();
if px == qx && py == -qy {
vx - px
} else if p == q {
@ -123,18 +146,18 @@ impl EllipticCurvePoint {
let mut f = FiniteFieldElement::new(U512::from(1u8), prime);
let mut t = p.clone();
let mut s = m.bits();
let s = m.bits();
let mut i = 1usize;
//println!("1 to {}", s);
while i < s {
//println!("ARR: {}", m.bit(i));
//println!("I: {}", i);
let gf = Self::g(t,t,q);
let gf = Self::g(t, t, q);
f = f * f * gf;
//println!("Miller g: {}", gf);
t = t + t;
if m.bit(i) {
f = f * Self::g(t, p,q);
f = f * Self::g(t, p, q);
t = t + p;
}
i += 1;
@ -169,13 +192,10 @@ impl Display for EllipticCurvePoint {
impl EllipticCurvePoint {
pub fn check(self) -> bool {
match self {
EllipticCurvePoint::Point { x, y, a, b } => {
y * y == x * x * x + a * x + b
},
EllipticCurvePoint::Point { x, y, a, b } => y * y == x * x * x + a * x + b,
EllipticCurvePoint::Infinity => true,
}
}
}
impl Neg for EllipticCurvePoint {
@ -185,7 +205,7 @@ impl Neg for EllipticCurvePoint {
if let EllipticCurvePoint::Point { x, y, a, b } = self {
EllipticCurvePoint::Point { x, y: -y, a, b }
} else {
return self
return self;
}
}
}
@ -195,35 +215,38 @@ impl Add for EllipticCurvePoint {
fn add(self, rhs: Self) -> Self::Output {
match self.clone() {
EllipticCurvePoint::Point { x: x1, y: y1, a, b } => {
match rhs {
EllipticCurvePoint::Point { x: x2, y: y2, a: a2, b: b2 } => {
let p = x1.p;
if a != a2 || b != b2 {
panic!("Cannot add different curve point.");
}
EllipticCurvePoint::Point { x: x1, y: y1, a, b } => match rhs {
EllipticCurvePoint::Point {
x: x2,
y: y2,
a: a2,
b: b2,
} => {
let p = x1.p;
if a != a2 || b != b2 {
panic!("Cannot add different curve point.");
}
if x1 == x2 && y2 == y1 - y1 - y1 {
return EllipticCurvePoint::Infinity
}
if x1 == x2 && y2 == y1 - y1 - y1 {
return EllipticCurvePoint::Infinity;
}
let l = if x1 == x2 && y1 == y2 {
let t = x1 * x1 * FiniteFieldElement::new(U512::from(3u8), p) + a;
let u = y1 * FiniteFieldElement::new(U512::from(2), p);
let a = t / u;
a
} else {
(y2 - y1) / (x2 - x1)
};
let x = l * l - x1 - x2;
let y = l * (x1 - x) - y1;
let l = if x1 == x2 && y1 == y2 {
let t = x1 * x1 * FiniteFieldElement::new(U512::from(3u8), p) + a;
let u = y1 * FiniteFieldElement::new(U512::from(2), p);
let a = t / u;
a
} else {
(y2 - y1) / (x2 - x1)
};
let x = l * l - x1 - x2;
let y = l * (x1 - x) - y1;
EllipticCurvePoint::Point { x, y, a, b }
},
EllipticCurvePoint::Infinity => self
EllipticCurvePoint::Point { x, y, a, b }
}
EllipticCurvePoint::Infinity => self,
},
EllipticCurvePoint::Infinity => rhs
EllipticCurvePoint::Infinity => rhs,
}
}
}

View File

@ -1,11 +1,6 @@
use serde::{Deserialize, Deserializer, Serialize};
use serde::{Deserialize, Serialize};
use crate::gpsl::{permission::Permission, variable::Variable};
use std::{
io::{BufRead, BufReader, Read, Write},
net::TcpStream,
sync::{Arc, Mutex},
};
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum ExternalFuncStatus {

View File

@ -1,5 +1,3 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
@ -41,7 +39,7 @@ pub enum Node {
rhs: Box<Node>,
},
Number {
value: usize,
value: i64,
},
Text {
value: String,
@ -88,7 +86,7 @@ impl Node {
Box::new(Node::Operator { kind, lhs, rhs })
}
pub fn new_num_node(value: usize) -> Box<Node> {
pub fn new_num_node(value: i64) -> Box<Node> {
Box::new(Node::Number { value })
}

View File

@ -1,9 +1,7 @@
use crate::gpsl::node::*;
use crate::gpsl::token::*;
use crate::gpsl::tokenizer::*;
use env_logger;
use log::*;
use log::{debug, error, info, warn};
use log::debug;
use std::collections::HashMap;
#[derive(Clone)]
@ -33,7 +31,6 @@ impl Parser {
pub fn function(&mut self) -> Result<Box<Node>, String> {
// parse attribute
let attribute = if self.tokenizer.current_token().str == String::from("#") {
println!("{:?}", self.tokenizer.current_token());
Some(self.attribute()?)
} else {
Some(Box::new(Node::Attribute {
@ -42,8 +39,6 @@ impl Parser {
}))
};
println!("{:?}", self.tokenizer.current_token());
if self
.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from("fn"))
@ -92,7 +87,7 @@ impl Parser {
/*
program: stmt* ;
*/
pub fn program(&mut self) -> Result<Vec<Box<Node>>, String> {
let mut nodes: Vec<Box<Node>> = vec![];
loop {
@ -102,7 +97,7 @@ impl Parser {
return Ok(nodes);
}
}
}
}*/
/*
stmt: let

View File

@ -12,6 +12,6 @@ pub enum TokenKind {
#[derive(Clone, Debug)]
pub struct Token {
pub kind: TokenKind,
pub num: usize,
pub num: i64,
pub str: String,
}

View File

@ -76,7 +76,7 @@ impl Tokenizer {
Ok(val.to_string())
}
pub fn expect_number(&mut self) -> Result<usize, String> {
pub fn expect_number(&mut self) -> Result<i64, String> {
let kind = self.current_token().kind;
debug!("Expect NUM {:?}", self.current_token());
if kind != TokenKind::NUMBER {
@ -102,7 +102,7 @@ impl Tokenizer {
}
}
pub fn create_number(num: usize) -> Token {
pub fn create_number(num: i64) -> Token {
Token {
kind: TokenKind::NUMBER,
num: num,

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub enum Variable {
Number { value: usize },
Number { value: i64 },
Text { value: String },
Return { value: Box<Variable> },
None {},

View File

@ -6,7 +6,7 @@ use crate::gpsl::variable::*;
use log::*;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, VecDeque};
use std::io::{BufRead, BufReader, Read, Write};
use std::io::{BufRead, BufReader, Write};
use std::net::TcpStream;
use std::string::*;
use std::sync::{Arc, Mutex};
@ -106,7 +106,7 @@ impl GPSL {
None
}
pub fn extract_number(node: Variable) -> Result<usize, String> {
pub fn extract_number(node: Variable) -> Result<i64, String> {
match node {
Variable::Number { value } => Ok(value),
_ => Err(String::from("Not a number")),
@ -148,7 +148,6 @@ impl GPSL {
args: args.clone(),
})
.unwrap();
println!("{}", server_function_call);
stream
.write_fmt(format_args!("{}\n", server_function_call))
@ -480,16 +479,15 @@ impl GPSL {
(accept, reject)
};
let mode = if let Node::Mode { mode } = *mode.unwrap_or(Box::new(Node::None)) {
let _ = if let Node::Mode { mode } = *mode.unwrap_or(Box::new(Node::None)) {
mode
} else {
"".to_string()
};
println!("Mode: {}", mode);
self.blocks.push_front(Block {
accept: accept,
reject: reject,
accept,
reject,
variables: HashMap::new(),
is_split: false,
});

View File

@ -3,9 +3,8 @@ use gpsl::external_function::ExternalFuncReturn;
use gpsl::external_function::ExternalFuncStatus;
use gpsl::node::Node;
use gpsl::node::NodeKind;
use gpsl::variable::Variable;
use gpsl::vm::gpsl::ServerFunctionCall;
use gpsl::{external_function::STD_FUNC, parser::*, source::*, tokenizer::*, vm::gpsl::*};
use gpsl::{external_function::STD_FUNC, source::*, tokenizer::*, vm::gpsl::*};
use log::*;
use std::env;
use std::io::BufRead;
@ -89,6 +88,8 @@ fn listen_tcp_server(port: u16) -> TcpStream {
}
fn main() {
env::set_var("RUST_LOG", "info");
env_logger::init();
let args = Args::parse();
match &*args.mode {
@ -105,47 +106,63 @@ fn main() {
}
fn server(args: Args) {
let mut stream = listen_tcp_server(args.port.unwrap());
loop {
info!("GPSL Server listening on port {}", args.port.unwrap());
let mut stream = listen_tcp_server(args.port.unwrap());
debug!("Receiving functions...");
let mut buf = String::default();
BufReader::new(stream.try_clone().unwrap())
.read_line(&mut buf)
.unwrap();
debug!("Receiving functions...");
let mut buf = String::default();
BufReader::new(stream.try_clone().unwrap())
.read_line(&mut buf)
.unwrap();
let functions: HashMap<String, Box<Node>> = serde_json::from_str(&buf).unwrap();
debug!("Received: {:?}", functions);
let functions: HashMap<String, Box<Node>> = serde_json::from_str(&buf).unwrap();
debug!("Received: {:?}", functions);
let mut gpsl = GPSL::new(
Source::new(String::default()),
Some(functions),
Some(HashMap::new()),
Some(HashMap::new()),
vec![STD_FUNC],
);
let mut gpsl = GPSL::new(
Source::new(String::default()),
Some(functions),
Some(HashMap::new()),
Some(HashMap::new()),
vec![STD_FUNC],
);
debug!("Receiving function call...");
BufReader::new(stream.try_clone().unwrap())
.read_line(&mut buf)
.unwrap();
debug!("Received");
debug!("{}", buf);
stream.write_fmt(format_args!("received\n")).unwrap();
let function_call: ServerFunctionCall = serde_json::from_str(&buf).unwrap();
loop {
debug!("Receiving function call...");
buf = String::default();
if let Err(_) = BufReader::new(stream.try_clone().unwrap()).read_line(&mut buf) {
break;
}
debug!("Received");
debug!("{}", buf);
let result = gpsl.run(function_call.name, function_call.args);
let external_function_return = ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: Some(result.unwrap()),
};
let function_call: ServerFunctionCall =
if let Ok(function_call) = serde_json::from_str(&buf) {
function_call
} else {
break;
};
debug!("Sending result...");
stream
.write_fmt(format_args!(
"{}\n",
serde_json::to_string(&external_function_return).unwrap()
))
.unwrap();
trace!("Running function: {}", function_call.name);
let result = gpsl.run(function_call.name, function_call.args);
let external_function_return = ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: Some(result.unwrap()),
};
debug!("Sending result...");
if let Err(_) = stream.write_fmt(format_args!(
"{}\n",
serde_json::to_string(&external_function_return).unwrap()
)) {
break;
}
}
stream.shutdown(std::net::Shutdown::Both).unwrap();
}
}
fn client(args: Args) {
@ -167,7 +184,6 @@ fn client(args: Args) {
Node::Function { attribute, .. } => match *(attribute.unwrap()) {
Node::Attribute { name, args } => {
if name == String::from("server") {
println!("{:?}", function);
let ip = {
let mut t_ip = None;
for arg in args {
@ -175,7 +191,6 @@ fn client(args: Args) {
Node::Operator { kind, lhs, rhs } => {
if kind == NodeKind::ASSIGN {
if lhs.extract_string() == String::from("ip") {
println!("IP: {}", rhs.extract_string());
Some(rhs.extract_string())
} else {
None
@ -213,6 +228,13 @@ fn client(args: Args) {
serde_json::to_string(&functions).unwrap()
))
.unwrap();
let mut buf = String::default();
BufReader::new(stream.try_clone().unwrap())
.read_line(&mut buf)
.unwrap();
if buf != String::from("received\n") {
panic!("Server did not receive functions");
}
servers.insert(ip, Arc::new(Mutex::new(stream)));
}