add v6 syntax\, reorganize stuff
This commit is contained in:
parent
49b33cdbfd
commit
00e7037128
|
@ -25,11 +25,13 @@ like.
|
|||
are coming from object oriented languages you can think of self as
|
||||
"primitive types"
|
||||
|
||||
#+begin_example
|
||||
type «type_token» {
|
||||
! values
|
||||
#+begin_src ztl
|
||||
type «token» {
|
||||
init() {
|
||||
// values
|
||||
}
|
||||
}
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
* Substantial Types
|
||||
:PROPERTIES:
|
||||
|
@ -85,9 +87,9 @@ normal string
|
|||
|
||||
="«utf8 encoded characters»"=
|
||||
|
||||
multiline literal string (also used for string interpolation like in JS)
|
||||
string interpolation
|
||||
|
||||
=`«utf8 encoded characters» {some_var}`=
|
||||
="«utf8 encoded characters» ${some_var}"=
|
||||
|
||||
** logical
|
||||
:PROPERTIES:
|
||||
|
@ -110,11 +112,11 @@ monad above and is unwrapped in a similar way. You could also think of
|
|||
it as every variable being able to have "the type" and also "error" as a
|
||||
possible value.
|
||||
|
||||
#+begin_example
|
||||
set error to %"something borked";
|
||||
set some_var to error ?? 0;
|
||||
set some_var to error ?? panic(error);
|
||||
#+end_example
|
||||
#+begin_src ztl
|
||||
let rr = err("something borked");
|
||||
let var = rr ?? 0; // value is 0
|
||||
let other_var = rr ?? panic(rr); // will panic
|
||||
#+end_src ztl
|
||||
|
||||
** datastructure
|
||||
:PROPERTIES:
|
||||
|
@ -133,15 +135,13 @@ Types that can be indexes are numbers and strings (no objects);
|
|||
syntax (yes I was nice and kept the syntax the same as most C like
|
||||
langs)
|
||||
|
||||
#+begin_example
|
||||
! array same as a map of int->«type»
|
||||
#+begin_src ztl
|
||||
// array same as a map of int to «type»
|
||||
let «variable» = [val1, val2, ...];
|
||||
|
||||
set «variable» to [val1, val2, ...] as «type»[];
|
||||
|
||||
! or as a map
|
||||
|
||||
set «variable» to {key1: val1, key2: val2, ...} as «type»->«type»;
|
||||
#+end_example
|
||||
// or as a map
|
||||
let «variable» = {key1: val1, key2: val2, ...};
|
||||
#+end_src ztl
|
||||
|
||||
*** tunnel
|
||||
:PROPERTIES:
|
||||
|
@ -155,10 +155,10 @@ described in "tunnel" section
|
|||
:END:
|
||||
The following is a list of global operators and their effect:
|
||||
|
||||
- =!=
|
||||
- =//=
|
||||
- comment
|
||||
- =!!=
|
||||
- block comment (looks for another !! to close)
|
||||
- =/**/=
|
||||
- block comment
|
||||
- =??=
|
||||
- unwrap or
|
||||
- =+=
|
||||
|
@ -186,9 +186,6 @@ The following is a list of global operators and their effect:
|
|||
- curry a function into another function (like haskell shove)
|
||||
- =.=
|
||||
- accessor
|
||||
- =..=
|
||||
- expander
|
||||
- (1..10) is the same as writing (1,2,3,4,5,6,7,8,9,10)
|
||||
- =++=
|
||||
- inline add 1
|
||||
- =--=
|
||||
|
@ -237,41 +234,55 @@ The following is a list of global operators and their effect:
|
|||
:PROPERTIES:
|
||||
:CUSTOM_ID: keywords
|
||||
:END:
|
||||
=to=
|
||||
|
||||
set operator
|
||||
=let=
|
||||
|
||||
#+begin_example
|
||||
set «token» to 0;
|
||||
#+end_example
|
||||
let operator
|
||||
|
||||
#+begin_src ztl
|
||||
let «token» = 0;
|
||||
#+end_src ztl
|
||||
|
||||
=is=
|
||||
|
||||
checks if a object is of that type
|
||||
=if («token» is i32) { stdout.print("hello yes self is i32?"); }=
|
||||
|
||||
also used for setting constants =const purple is Color(255, 255, 0);=
|
||||
#+begin_src ztl
|
||||
if («token» is i32) {
|
||||
print("hello yes self is i32?");
|
||||
}
|
||||
#+end_src ztl
|
||||
|
||||
also used for letting constants
|
||||
|
||||
#+begin_src ztl
|
||||
const PURPLE is Color(255, 255, 0);
|
||||
#+end_src ztl
|
||||
|
||||
=as=
|
||||
|
||||
coerces a type as another type if possible
|
||||
=set «token» to 0; ! default is i32 some_functon_that_needs_a_i8(«token» as i8);=
|
||||
|
||||
#+begin_src ztl
|
||||
let «token» = 0; // default is i32
|
||||
some_functon(«token» as i8); // needs an i8
|
||||
#+end_src ztl
|
||||
|
||||
=in=
|
||||
|
||||
checks if a object's type, or a type impls another type
|
||||
|
||||
#+begin_example
|
||||
#+begin_src ztl
|
||||
if («token» in Tunnel) {
|
||||
stdout.print("im tunnel-able");
|
||||
print("im tunnel-able");
|
||||
}
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
also used inside of the for loops
|
||||
|
||||
#+begin_example
|
||||
#+begin_src ztl
|
||||
for («token» in «collection») { «body» }
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
** Object
|
||||
:PROPERTIES:
|
||||
|
@ -279,9 +290,9 @@ for («token» in «collection») { «body» }
|
|||
:END:
|
||||
An object is an invoked type.
|
||||
|
||||
#+begin_example
|
||||
set «variable» to «type»(«fields», …);
|
||||
#+end_example
|
||||
#+begin_src ztl
|
||||
let «variable» = «type»(«fields», …);
|
||||
#+end_src ztl
|
||||
|
||||
** Tunnel
|
||||
:PROPERTIES:
|
||||
|
@ -335,19 +346,14 @@ connected tunnel
|
|||
=success? : tunnel_object.walk(path_or_endpoint)= -> moves around the
|
||||
filesystem or through the graph
|
||||
|
||||
#+begin_example
|
||||
set endpoint to 9p(endpoint_str);
|
||||
set tunnel to endpoint.attach(user, auth);
|
||||
set data to tunnel.open("\some\resource").read();
|
||||
stdout.write(data);
|
||||
#+begin_src ztl
|
||||
let endpoint = Tunnel("protocol://path/to/source");
|
||||
let tunnel = endpoint.attach(user, auth);
|
||||
let data = tunnel.open("/some/resource").read();
|
||||
std.write(data); //print(data);
|
||||
data.flush();
|
||||
endpoint.clunk();
|
||||
#+end_example
|
||||
|
||||
in "terminal mode" the default tunnel is stdout
|
||||
|
||||
in "web mode" the default tunnels are log, info, trace, warn, error, but
|
||||
note these are all special tunnels which only accept write commands
|
||||
#+end_src ztl
|
||||
|
||||
** Functions
|
||||
:PROPERTIES:
|
||||
|
@ -358,11 +364,11 @@ always have a "default type" for all constant values or a developer can
|
|||
use the =as= keyword we do not have to define all values like in C,
|
||||
while keeping the same type safety as a more strongly typed language.
|
||||
|
||||
#+begin_example
|
||||
fn «token» («type» «parameter», ...) «return_type» {
|
||||
«instructions»
|
||||
#+begin_src ztl
|
||||
fn «token» («parameter» «type», ...) «return_type» {
|
||||
«body»
|
||||
}
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
- Built in transtypes
|
||||
- sort
|
||||
|
@ -379,45 +385,43 @@ fn «token» («type» «parameter», ...) «return_type» {
|
|||
:PROPERTIES:
|
||||
:CUSTOM_ID: loops
|
||||
:END:
|
||||
#+begin_example
|
||||
#+begin_src ztl
|
||||
for («token» in «collection») { «body» }
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
iterates through each object in the collection setting it to token
|
||||
|
||||
#+begin_example
|
||||
#+begin_src ztl
|
||||
while («boolean expression») { «body» }
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
loops until the expression is false
|
||||
|
||||
#+begin_example
|
||||
#+begin_src ztl
|
||||
loop { «body» }
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
loops infinitely until break or return
|
||||
|
||||
#+begin_example
|
||||
loop { «body» } until(«boolean expression»);
|
||||
#+end_example
|
||||
#+begin_src ztl
|
||||
do (let «variable» = initial_value, end_value, increment) { «body» }
|
||||
#+end_src ztl
|
||||
|
||||
always loops first and then until the expression is false
|
||||
loops from initial value to end value by increment value
|
||||
|
||||
*** branching
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: branching
|
||||
:END:
|
||||
#+begin_example
|
||||
match «token» {
|
||||
'a' -> actionA
|
||||
'x' -> actionX
|
||||
'y'..'z' -> {
|
||||
actionY
|
||||
actionZ
|
||||
}
|
||||
_ -> actionNoMatch
|
||||
#+begin_src ztl
|
||||
if («boolean expression») {
|
||||
|
||||
} else if («boolean expression») {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
*** exceptions
|
||||
:PROPERTIES:
|
||||
|
@ -425,11 +429,11 @@ match «token» {
|
|||
:END:
|
||||
take a look at error's, but you can panic on an error like self:
|
||||
|
||||
#+begin_example
|
||||
panic(#"error message");
|
||||
panic(#3);
|
||||
#+begin_src ztl
|
||||
panic(err("error message"));
|
||||
panic(err(3));
|
||||
panic(«some_error_token»);
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
** Localization
|
||||
:PROPERTIES:
|
||||
|
@ -437,9 +441,9 @@ panic(«some_error_token»);
|
|||
:END:
|
||||
will look up the text of «token» in the linked localization.json file
|
||||
|
||||
#+begin_example
|
||||
$«token»
|
||||
#+end_example
|
||||
#+begin_src ztl
|
||||
#«token»
|
||||
#+end_src ztl
|
||||
|
||||
#+begin_src json
|
||||
{
|
||||
|
@ -465,13 +469,13 @@ can even use localization tokens to create config files. Since
|
|||
everything is lazily compiled jit anyways it (in theory) doesn't hurt
|
||||
pertypeance much
|
||||
|
||||
#+begin_example
|
||||
use "https://code.example.com/some_library/some_file.ztl"
|
||||
#+end_example
|
||||
#+begin_src ztl
|
||||
use "https://git.alfrescocavern.com/some_library/some_file.ztl"
|
||||
#+end_src ztl
|
||||
|
||||
#+begin_example
|
||||
#+begin_src ztl
|
||||
use "./some_local_file.ztl"
|
||||
#+end_example
|
||||
#+end_src ztl
|
||||
|
||||
** Testing
|
||||
:PROPERTIES:
|
||||
|
@ -481,9 +485,9 @@ use "./some_local_file.ztl"
|
|||
:PROPERTIES:
|
||||
:CUSTOM_ID: assertion
|
||||
:END:
|
||||
#+begin_example
|
||||
assert(«expression», «expected output») ! returns «error or none»
|
||||
#+end_example
|
||||
#+begin_src ztl
|
||||
assert(«expression», «expected output») //returns «error or none»
|
||||
#+end_src ztl
|
||||
|
||||
** Measurements
|
||||
:PROPERTIES:
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
(set purple (255 255 0))
|
||||
|
||||
:main {
|
||||
800 :screen_width set
|
||||
450 :screen_height set
|
||||
|
||||
argv split
|
||||
:username set
|
||||
:password set
|
||||
|
||||
(username (0.0 1.0 2.0) purple) :me set
|
||||
(password (me login)) :players set
|
||||
|
||||
() () me shatter pop exch pop shatter cons
|
||||
10.0 add cons
|
||||
10.0 add cons
|
||||
me shatter pop exch pop cons
|
||||
(0.0 1.0 0.0) cons
|
||||
45.0 cons
|
||||
"CAMERA_PERSPECTIVE" cons
|
||||
:camera set
|
||||
|
||||
screen_width screen_height "zwl client : raylib" init_window
|
||||
60 set_target_fps
|
||||
|
||||
{
|
||||
|
||||
(* Do handling in here *)
|
||||
|
||||
end_mode_3d
|
||||
|
||||
end_drawing
|
||||
} window_should_close repeat (* Detect window close button or ESC key *)
|
||||
|
||||
me logout :players set
|
||||
close_window (*Close window and OpenGL context *)
|
||||
} set
|
||||
|
||||
main
|
|
@ -16,20 +16,18 @@
|
|||
:color color
|
||||
} type
|
||||
|
||||
:login {
|
||||
:player 0 check
|
||||
:str 1 check
|
||||
:login (player str -> nil) {
|
||||
|
||||
(* do the login here *)
|
||||
} fn
|
||||
|
||||
(255 255 0) :purple color
|
||||
255 255 0 :purple color
|
||||
|
||||
:main {
|
||||
:main (i32 char** -> i32) {
|
||||
800 :screen_width i32
|
||||
450 :screen_height i32
|
||||
|
||||
argv split
|
||||
pop shatter
|
||||
:username str
|
||||
:password str
|
||||
|
||||
|
@ -102,4 +100,4 @@
|
|||
|
||||
} fn
|
||||
|
||||
main
|
||||
argv split count main
|
|
@ -0,0 +1,64 @@
|
|||
--mod-version:3
|
||||
local syntax = require 'core.syntax'
|
||||
|
||||
syntax.add {
|
||||
name = "Zongor's Transpiler Language",
|
||||
files = { "%.ztl$" },
|
||||
comment = "!",
|
||||
block_comment = { '!!', '!!' },
|
||||
patterns = {
|
||||
{ pattern = { "!!", "!!" }, type = "comment" }, -- tested ok
|
||||
{ pattern = "!.*", type = "comment" },
|
||||
{ pattern = { '"', '"', '\\' }, type = "string" },
|
||||
{ pattern = { "'", "'", '\\' }, type = "string" },
|
||||
{ pattern = ";", type = "operator" },
|
||||
{ pattern = "[%a_][%w_]*()%s*%(", type = {"function", "normal"} },
|
||||
{ pattern = "[viu][%d_]+", type = "keyword2" },
|
||||
{ pattern = "[A-Z][%w_]*", type = "keyword2" },
|
||||
{ pattern = "[9][%w_]*", type = "keyword2" },
|
||||
{ pattern = "-?%.?%d+f?", type = "number" },
|
||||
},
|
||||
symbols = {
|
||||
["fn"] = "keyword",
|
||||
["to"] = "keyword",
|
||||
["in"] = "keyword",
|
||||
["is"] = "keyword",
|
||||
["as"] = "keyword",
|
||||
["use"] = "keyword",
|
||||
["set"] = "keyword",
|
||||
["if"] = "keyword",
|
||||
["else"] = "keyword",
|
||||
["for"] = "keyword",
|
||||
["loop"] = "keyword",
|
||||
["while"] = "keyword",
|
||||
["push"] = "keyword",
|
||||
["pop"] = "keyword",
|
||||
["return"] = "keyword",
|
||||
["const"] = "keyword",
|
||||
["type"] = "keyword",
|
||||
["this"] = "keyword",
|
||||
|
||||
["eq"] = "keyword",
|
||||
["ne"] = "keyword",
|
||||
["mod"] = "keyword",
|
||||
["not"] = "keyword",
|
||||
["and"] = "keyword",
|
||||
["or"] = "keyword",
|
||||
["xor"] = "keyword",
|
||||
["band"] = "keyword",
|
||||
["bor"] = "keyword",
|
||||
["bxor"] = "keyword",
|
||||
["srl"] = "keyword",
|
||||
["sll"] = "keyword",
|
||||
|
||||
["char"] = "keyword2",
|
||||
["str"] = "keyword2",
|
||||
["f16"] = "keyword2",
|
||||
["f32"] = "keyword2",
|
||||
["f64"] = "keyword2",
|
||||
["f128"] = "keyword2",
|
||||
|
||||
["true"] = "literal",
|
||||
["false"] = "literal",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
fn build(ProjectConfig c) {
|
||||
c.name("MMO Project");
|
||||
c.mode("dev");
|
||||
|
||||
c.client([
|
||||
LanguageSettings(
|
||||
"c", ! lang
|
||||
"src/client.ztl", ! file
|
||||
"client/", ! out path
|
||||
[ ! ffi settings
|
||||
FFISetting {
|
||||
"raylib", ! libary name
|
||||
"$RAYLIB_PATH/libraylib.a", ! path
|
||||
"./", ! local path
|
||||
"make build", ! build command
|
||||
}
|
||||
]
|
||||
)
|
||||
]);
|
||||
|
||||
c.server([
|
||||
LanguageSettings(
|
||||
"javascript",
|
||||
"src/server.ztl",
|
||||
"server/"
|
||||
)
|
||||
]);
|
||||
|
||||
c.common([
|
||||
LanguageSettings(
|
||||
"c",
|
||||
"src/common.ztl",
|
||||
"client/"
|
||||
},
|
||||
LanguageSettings(
|
||||
"javascript",
|
||||
"src/common.ztl",
|
||||
"server/"
|
||||
),
|
||||
LanguageSettings(
|
||||
"sqlite",
|
||||
"src/common.ztl",
|
||||
"db/"
|
||||
)
|
||||
]);
|
||||
|
||||
c.build();
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
use "common.ztl";
|
||||
use "raylib" as rl;
|
||||
|
||||
fn main (i32 argc, str[] argv) i32 {
|
||||
set screen_width to 800 as i32;
|
||||
set screen_height to 450 as i32;
|
||||
|
||||
set username to argv[0];
|
||||
set password to argv[1];
|
||||
|
||||
set server to 9p("localhost:25565");
|
||||
|
||||
set me to Player(
|
||||
server,
|
||||
username,
|
||||
Vec(0.0, 1.0, 2.0),
|
||||
purple
|
||||
);
|
||||
|
||||
set players to me.login(password);
|
||||
|
||||
set camera to rl.Camera3D(
|
||||
Vec(0.0, 1.0, 0.0),
|
||||
45.0,
|
||||
CAMERA_PERSPECTIVE,
|
||||
Vec(me.pos.x + 10.0,
|
||||
me.pos.y + 10.0,
|
||||
me.pos.z),
|
||||
me.pos
|
||||
);
|
||||
|
||||
rl.init_window("zwl client : raylib", screen_width, screen_height);
|
||||
rl.set_target_fps(60);
|
||||
|
||||
!!
|
||||
Main game loop
|
||||
!!
|
||||
while ( not rl.window_should_close() ) { ! Detect window close button or ESC key
|
||||
|
||||
set player_updated to false;
|
||||
|
||||
if (rl.is_key_down(KEY_RIGHT)) {
|
||||
set me.pos.x to (me.pos.x + 0.2);
|
||||
set player_updated to true;
|
||||
}
|
||||
|
||||
if (rl.is_key_down(KEY_LEFT)) {
|
||||
set me.pos.x to (me.pos.x + 0.2);
|
||||
set player_updated to true;
|
||||
}
|
||||
|
||||
if (rl.is_key_down(KEY_DOWN)) {
|
||||
set me.pos.z to (me.pos.z + 0.2);
|
||||
set player_updated to true;
|
||||
}
|
||||
|
||||
if (rl.is_key_down(KEY_UP)) {
|
||||
set me.pos.z to (me.pos.z - 0.2);
|
||||
set player_updated to true;
|
||||
}
|
||||
|
||||
me.sync_camera(camera);
|
||||
|
||||
if (player_updated) {
|
||||
set players to me.move();
|
||||
} else {
|
||||
set players to me.ping();
|
||||
}
|
||||
|
||||
rl.begin_drawing();
|
||||
rl.clear_background(RAYWHITE);
|
||||
|
||||
rl.begin_mode_3d(camera);
|
||||
|
||||
! Draw floor
|
||||
rl.draw_grid(30, 1.0);
|
||||
|
||||
rl.draw_cube(me.pos, 0.5, 0.5, 0.5, me.apperance);
|
||||
|
||||
for (player in players) {
|
||||
rl.draw_cube(player.pos, 0.5, 0.5, 0.5, player.apperance);
|
||||
}
|
||||
|
||||
rl.end_mode_3d();
|
||||
|
||||
rl.end_drawing();
|
||||
}
|
||||
|
||||
me.logout();
|
||||
close_window(); ! Close window and OpenGL context
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
type Vec {
|
||||
init(f32 x, f32 y, f32 z) {
|
||||
set this.x to x;
|
||||
set this.y to y;
|
||||
set this.z to z;
|
||||
}
|
||||
}
|
||||
|
||||
type Color {
|
||||
init(i8 r, i8 g, i8 b) {
|
||||
set this.r to r;
|
||||
set this.g to g;
|
||||
set this.b to b;
|
||||
}
|
||||
}
|
||||
|
||||
type Player {
|
||||
init (9p server, str username, Vec pos, Color color) {
|
||||
set this.server to server;
|
||||
set this.username to username;
|
||||
set this.pos to pos;
|
||||
set this.color to color;
|
||||
}
|
||||
|
||||
login (str password) Player[] {
|
||||
this.server.auth(this.username, password);
|
||||
set this.players to server.open("players");
|
||||
return players.read();
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.players.flush();
|
||||
this.server.clunk();
|
||||
}
|
||||
}
|
||||
|
||||
const purple is Color(255, 255, 0);
|
|
@ -0,0 +1,75 @@
|
|||
use "common.ztl";
|
||||
|
||||
fn main (i32 argc, str[] argv) i32 {
|
||||
set s to 9p (
|
||||
version,
|
||||
auth,
|
||||
error,
|
||||
flush,
|
||||
attach,
|
||||
walk,
|
||||
open,
|
||||
create,
|
||||
read,
|
||||
write,
|
||||
clunk,
|
||||
remove,
|
||||
stat,
|
||||
);
|
||||
|
||||
s.host("0.0.0.0:25565");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fn version(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn auth(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn error(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn flush(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn attach(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn walk(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn open(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn create(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn read(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn write(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn clunk(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn remove(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn stat(9pmsg m) {
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
--mod-version:3
|
||||
local syntax = require 'core.syntax'
|
||||
|
||||
syntax.add {
|
||||
name = "Zongor's Transpiler Language",
|
||||
files = { "%.ztl$" },
|
||||
comment = "!",
|
||||
block_comment = { '!!', '!!' },
|
||||
patterns = {
|
||||
{ pattern = { "!!", "!!" }, type = "comment" }, -- tested ok
|
||||
{ pattern = "!.*", type = "comment" },
|
||||
{ pattern = { '"', '"', '\\' }, type = "string" },
|
||||
{ pattern = { "'", "'", '\\' }, type = "string" },
|
||||
{ pattern = ";", type = "operator" },
|
||||
{ pattern = "[%a_][%w_]*()%s*%(", type = {"function", "normal"} },
|
||||
{ pattern = "[viu][%d_]+", type = "keyword2" },
|
||||
{ pattern = "[A-Z][%w_]*", type = "keyword2" },
|
||||
{ pattern = "[9][%w_]*", type = "keyword2" },
|
||||
{ pattern = "-?%.?%d+f?", type = "number" },
|
||||
},
|
||||
symbols = {
|
||||
["fn"] = "keyword",
|
||||
["to"] = "keyword",
|
||||
["in"] = "keyword",
|
||||
["is"] = "keyword",
|
||||
["as"] = "keyword",
|
||||
["use"] = "keyword",
|
||||
["set"] = "keyword",
|
||||
["if"] = "keyword",
|
||||
["else"] = "keyword",
|
||||
["for"] = "keyword",
|
||||
["loop"] = "keyword",
|
||||
["while"] = "keyword",
|
||||
["push"] = "keyword",
|
||||
["pop"] = "keyword",
|
||||
["return"] = "keyword",
|
||||
["const"] = "keyword",
|
||||
["type"] = "keyword",
|
||||
["this"] = "keyword",
|
||||
|
||||
["eq"] = "keyword",
|
||||
["ne"] = "keyword",
|
||||
["mod"] = "keyword",
|
||||
["not"] = "keyword",
|
||||
["and"] = "keyword",
|
||||
["or"] = "keyword",
|
||||
["xor"] = "keyword",
|
||||
["band"] = "keyword",
|
||||
["bor"] = "keyword",
|
||||
["bxor"] = "keyword",
|
||||
["srl"] = "keyword",
|
||||
["sll"] = "keyword",
|
||||
|
||||
["char"] = "keyword2",
|
||||
["str"] = "keyword2",
|
||||
["f16"] = "keyword2",
|
||||
["f32"] = "keyword2",
|
||||
["f64"] = "keyword2",
|
||||
["f128"] = "keyword2",
|
||||
|
||||
["true"] = "literal",
|
||||
["false"] = "literal",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
fn build(ProjectConfig c) {
|
||||
c.name("MMO Project");
|
||||
c.mode("dev");
|
||||
|
||||
c.client([
|
||||
LanguageSettings(
|
||||
"c", ! lang
|
||||
"src/client.ztl", ! file
|
||||
"client/", ! out path
|
||||
[ ! ffi settings
|
||||
FFISetting (
|
||||
"raylib", ! libary name
|
||||
"$RAYLIB_PATH/libraylib.a", ! path
|
||||
"./", ! local path
|
||||
"make build", ! build command
|
||||
)
|
||||
]
|
||||
)
|
||||
]);
|
||||
|
||||
c.server([
|
||||
LanguageSettings(
|
||||
"javascript",
|
||||
"src/server.ztl",
|
||||
"server/"
|
||||
)
|
||||
]);
|
||||
|
||||
c.common([
|
||||
LanguageSettings(
|
||||
"c",
|
||||
"src/common.ztl",
|
||||
"client/"
|
||||
),
|
||||
LanguageSettings(
|
||||
"javascript",
|
||||
"src/common.ztl",
|
||||
"server/"
|
||||
),
|
||||
LanguageSettings(
|
||||
"sqlite",
|
||||
"src/common.ztl",
|
||||
"db/"
|
||||
)
|
||||
]);
|
||||
|
||||
c.build();
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
use "common.ztl";
|
||||
|
||||
fn main (argc num, argv str) num {
|
||||
let screen_width = 800;
|
||||
let screen_height = 450;
|
||||
|
||||
let username = argv[0];
|
||||
let password = argv[1];
|
||||
|
||||
let server = 9p("localhost:25565");
|
||||
|
||||
let me = Player(
|
||||
server,
|
||||
username,
|
||||
Vec(0.0, 1.0, 2.0),
|
||||
purple
|
||||
);
|
||||
|
||||
let players = me.login(password);
|
||||
|
||||
let camera = Camera3D(
|
||||
"CAMERA_PERSPECTIVE",
|
||||
45.0,
|
||||
Vec(0.0, 1.0, 0.0),
|
||||
Vec(me.pos.x + 10.0,
|
||||
me.pos.y + 10.0,
|
||||
me.pos.z),
|
||||
me.pos
|
||||
);
|
||||
|
||||
init_window("zwl client : raylib", screen_width, screen_height);
|
||||
target_fps(60);
|
||||
|
||||
while ( not window_should_close() ) {
|
||||
|
||||
let player_updated = false;
|
||||
|
||||
if (key_down(KEY_RIGHT)) {
|
||||
me.pos.x = (me.pos.x + 0.2);
|
||||
player_updated = true;
|
||||
}
|
||||
|
||||
if (key_down(KEY_RIGHT)) {
|
||||
me.pos.x = (me.pos.x + 0.2);
|
||||
player_updated = true;
|
||||
}
|
||||
|
||||
if (key_down(KEY_LEFT)) {
|
||||
me.pos.x = (me.pos.x + 0.2);
|
||||
player_updated = true;
|
||||
}
|
||||
|
||||
if (key_down(KEY_DOWN)) {
|
||||
me.pos.z = (me.pos.z + 0.2);
|
||||
player_updated = true;
|
||||
}
|
||||
|
||||
if (key_down(KEY_UP)) {
|
||||
me.pos.z = (me.pos.z - 0.2);
|
||||
player_updated = true;
|
||||
}
|
||||
|
||||
me.sync_camera(camera);
|
||||
|
||||
if (player_updated) {
|
||||
players = me.move();
|
||||
} else {
|
||||
players = me.ping();
|
||||
}
|
||||
|
||||
begin_drawing();
|
||||
clear_background(RAYWHITE);
|
||||
|
||||
begin_mode_3d(camera);
|
||||
|
||||
draw_grid(30, 1.0);
|
||||
|
||||
draw_cube(me.pos, 0.5, 0.5, 0.5, me.apperance);
|
||||
|
||||
for (player in players) {
|
||||
draw_cube(player.pos, 0.5, 0.5, 0.5, player.apperance);
|
||||
}
|
||||
|
||||
end_mode_3d();
|
||||
|
||||
end_drawing();
|
||||
}
|
||||
|
||||
me.logout();
|
||||
close_window();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
type Vec {
|
||||
init(x f32, y f32, z f32) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
|
||||
type Color {
|
||||
init(r i8, g i8, b i8) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
|
||||
type Camera3D {
|
||||
init(setting str, pov f32, up Vec, pos Vec, look Vec) {
|
||||
this.setting = setting;
|
||||
this.pov = pov;
|
||||
this.up = up;
|
||||
this.pos = pos;
|
||||
this.look = look;
|
||||
}
|
||||
}
|
||||
|
||||
type Player {
|
||||
init (server 9p, username str, pos Vec, color Color) {
|
||||
this.server = server;
|
||||
this.username = username;
|
||||
this.pos = pos;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
login (password str) Player[] {
|
||||
this.server.auth(this.username, password);
|
||||
this.players = server.open("players");
|
||||
return players.read();
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.players.flush();
|
||||
this.server.clunk();
|
||||
}
|
||||
}
|
||||
|
||||
const purple = Color(255, 255, 0);
|
|
@ -0,0 +1,75 @@
|
|||
use "common.ztl";
|
||||
|
||||
fn main (i32 argc, str[] argv) i32 {
|
||||
set s to 9p (
|
||||
version,
|
||||
auth,
|
||||
error,
|
||||
flush,
|
||||
attach,
|
||||
walk,
|
||||
open,
|
||||
create,
|
||||
read,
|
||||
write,
|
||||
clunk,
|
||||
remove,
|
||||
stat,
|
||||
);
|
||||
|
||||
s.host("0.0.0.0:25565");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fn version(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn auth(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn error(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn flush(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn attach(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn walk(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn open(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn create(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn read(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn write(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn clunk(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn remove(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn stat(9pmsg m) {
|
||||
|
||||
}
|
|
@ -4,61 +4,60 @@ local syntax = require 'core.syntax'
|
|||
syntax.add {
|
||||
name = "Zongor's Transpiler Language",
|
||||
files = { "%.ztl$" },
|
||||
comment = "!",
|
||||
block_comment = { '!!', '!!' },
|
||||
comment = "//",
|
||||
block_comment = { '/*', '*/' },
|
||||
patterns = {
|
||||
{ pattern = { "!!", "!!" }, type = "comment" }, -- tested ok
|
||||
{ pattern = "!.*", type = "comment" },
|
||||
{ pattern = { '"', '"', '\\' }, type = "string" },
|
||||
{ pattern = { "'", "'", '\\' }, type = "string" },
|
||||
{ pattern = ";", type = "operator" },
|
||||
{ pattern = "[%a_][%w_]*()%s*%(", type = {"function", "normal"} },
|
||||
{ pattern = "[viu][%d_]+", type = "keyword2" },
|
||||
{ pattern = "[A-Z][%w_]*", type = "keyword2" },
|
||||
{ pattern = "[9][%w_]*", type = "keyword2" },
|
||||
{ pattern = "-?%.?%d+f?", type = "number" },
|
||||
{ pattern = { "/*", "*/" }, type = "comment" },
|
||||
{ pattern = "//.*", type = "comment" },
|
||||
{ pattern = { '"', '"', '\\' }, type = "string" },
|
||||
{ pattern = { "'", "'", '\\' }, type = "string" },
|
||||
{ pattern = ";", type = "operator" },
|
||||
{ pattern = "[%a_][%w_]*()%s*%(", type = {"function", "normal"} },
|
||||
{ pattern = "[iu][%d_]+", type = "keyword2" },
|
||||
{ pattern = "[A-Z][%w_]*", type = "keyword2" },
|
||||
{ pattern = "-?%.?%d+f?", type = "number" },
|
||||
},
|
||||
symbols = {
|
||||
["fn"] = "keyword",
|
||||
["to"] = "keyword",
|
||||
["in"] = "keyword",
|
||||
["is"] = "keyword",
|
||||
["as"] = "keyword",
|
||||
["use"] = "keyword",
|
||||
["set"] = "keyword",
|
||||
["if"] = "keyword",
|
||||
["else"] = "keyword",
|
||||
["for"] = "keyword",
|
||||
["loop"] = "keyword",
|
||||
["while"] = "keyword",
|
||||
["push"] = "keyword",
|
||||
["pop"] = "keyword",
|
||||
["return"] = "keyword",
|
||||
["const"] = "keyword",
|
||||
["type"] = "keyword",
|
||||
["this"] = "keyword",
|
||||
|
||||
["eq"] = "keyword",
|
||||
["ne"] = "keyword",
|
||||
["mod"] = "keyword",
|
||||
["not"] = "keyword",
|
||||
["and"] = "keyword",
|
||||
["or"] = "keyword",
|
||||
["xor"] = "keyword",
|
||||
["band"] = "keyword",
|
||||
["bor"] = "keyword",
|
||||
["bxor"] = "keyword",
|
||||
["srl"] = "keyword",
|
||||
["sll"] = "keyword",
|
||||
|
||||
["char"] = "keyword2",
|
||||
["str"] = "keyword2",
|
||||
["f16"] = "keyword2",
|
||||
["f32"] = "keyword2",
|
||||
["f64"] = "keyword2",
|
||||
["f128"] = "keyword2",
|
||||
|
||||
["true"] = "literal",
|
||||
["false"] = "literal",
|
||||
["fn"] = "keyword",
|
||||
["to"] = "keyword",
|
||||
["in"] = "keyword",
|
||||
["is"] = "keyword",
|
||||
["as"] = "keyword",
|
||||
["use"] = "keyword",
|
||||
["set"] = "keyword",
|
||||
["if"] = "keyword",
|
||||
["else"] = "keyword",
|
||||
["for"] = "keyword",
|
||||
["loop"] = "keyword",
|
||||
["while"] = "keyword",
|
||||
["push"] = "keyword",
|
||||
["pop"] = "keyword",
|
||||
["return"] = "keyword",
|
||||
["const"] = "keyword",
|
||||
["type"] = "keyword",
|
||||
["this"] = "keyword",
|
||||
|
||||
["eq"] = "keyword",
|
||||
["ne"] = "keyword",
|
||||
["mod"] = "keyword",
|
||||
["not"] = "keyword",
|
||||
["and"] = "keyword",
|
||||
["or"] = "keyword",
|
||||
["xor"] = "keyword",
|
||||
["band"] = "keyword",
|
||||
["bor"] = "keyword",
|
||||
["bxor"] = "keyword",
|
||||
["srl"] = "keyword",
|
||||
["sll"] = "keyword",
|
||||
|
||||
["char"] = "keyword2",
|
||||
["str"] = "keyword2",
|
||||
["f16"] = "keyword2",
|
||||
["f32"] = "keyword2",
|
||||
["f64"] = "keyword2",
|
||||
["f128"] = "keyword2",
|
||||
|
||||
["true"] = "literal",
|
||||
["false"] = "literal",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -8,12 +8,12 @@ fn build(ProjectConfig c) {
|
|||
"src/client.ztl", ! file
|
||||
"client/", ! out path
|
||||
[ ! ffi settings
|
||||
FFISetting {
|
||||
FFISetting (
|
||||
"raylib", ! libary name
|
||||
"$RAYLIB_PATH/libraylib.a", ! path
|
||||
"./", ! local path
|
||||
"make build", ! build command
|
||||
}
|
||||
)
|
||||
]
|
||||
)
|
||||
]);
|
||||
|
@ -31,7 +31,7 @@ fn build(ProjectConfig c) {
|
|||
"c",
|
||||
"src/common.ztl",
|
||||
"client/"
|
||||
},
|
||||
),
|
||||
LanguageSettings(
|
||||
"javascript",
|
||||
"src/common.ztl",
|
||||
|
|
|
@ -1,93 +1,45 @@
|
|||
use "common.ztl";
|
||||
use "raylib" as rl;
|
||||
|
||||
fn main (i32 argc, str[] argv) i32 {
|
||||
set screen_width to 800 as i32;
|
||||
set screen_height to 450 as i32;
|
||||
fn main (argc int, argv str[]) int {
|
||||
let screen_width = 800;
|
||||
let screen_height = 450;
|
||||
|
||||
set username to argv[0];
|
||||
set password to argv[1];
|
||||
let username = argv[0];
|
||||
let password = argv[1];
|
||||
|
||||
set server to 9p("localhost:25565");
|
||||
|
||||
set me to Player(
|
||||
server,
|
||||
let me = Player(
|
||||
username,
|
||||
Vec(0.0, 1.0, 2.0),
|
||||
Vec3(0.0, 1.0, 2.0),
|
||||
purple
|
||||
);
|
||||
|
||||
set players to me.login(password);
|
||||
let players = me.login(password);
|
||||
|
||||
set camera to rl.Camera3D(
|
||||
Vec(0.0, 1.0, 0.0),
|
||||
45.0,
|
||||
CAMERA_PERSPECTIVE,
|
||||
Vec(me.pos.x + 10.0,
|
||||
me.pos.y + 10.0,
|
||||
me.pos.z),
|
||||
me.pos
|
||||
);
|
||||
let window = Window("zwl client", screen_width, screen_height);
|
||||
|
||||
rl.init_window("zwl client : raylib", screen_width, screen_height);
|
||||
rl.set_target_fps(60);
|
||||
while ( not window.should_close() ) {
|
||||
me.update();
|
||||
|
||||
!!
|
||||
Main game loop
|
||||
!!
|
||||
while ( not rl.window_should_close() ) { ! Detect window close button or ESC key
|
||||
window.begin_drawing();
|
||||
window.clear_background(WHITE);
|
||||
|
||||
set player_updated to false;
|
||||
|
||||
if (rl.is_key_down(KEY_RIGHT)) {
|
||||
set me.pos.x to (me.pos.x + 0.2);
|
||||
set player_updated to true;
|
||||
}
|
||||
|
||||
if (rl.is_key_down(KEY_LEFT)) {
|
||||
set me.pos.x to (me.pos.x + 0.2);
|
||||
set player_updated to true;
|
||||
}
|
||||
|
||||
if (rl.is_key_down(KEY_DOWN)) {
|
||||
set me.pos.z to (me.pos.z + 0.2);
|
||||
set player_updated to true;
|
||||
}
|
||||
window.begin_mode_3d(camera);
|
||||
|
||||
if (rl.is_key_down(KEY_UP)) {
|
||||
set me.pos.z to (me.pos.z - 0.2);
|
||||
set player_updated to true;
|
||||
}
|
||||
window.draw_grid(30, 1.0);
|
||||
|
||||
me.sync_camera(camera);
|
||||
|
||||
if (player_updated) {
|
||||
set players to me.move();
|
||||
} else {
|
||||
set players to me.ping();
|
||||
}
|
||||
|
||||
rl.begin_drawing();
|
||||
rl.clear_background(RAYWHITE);
|
||||
|
||||
rl.begin_mode_3d(camera);
|
||||
|
||||
! Draw floor
|
||||
rl.draw_grid(30, 1.0);
|
||||
|
||||
rl.draw_cube(me.pos, 0.5, 0.5, 0.5, me.apperance);
|
||||
window.draw_cube(me.pos, 0.5, 0.5, 0.5, me.apperance);
|
||||
|
||||
for (player in players) {
|
||||
rl.draw_cube(player.pos, 0.5, 0.5, 0.5, player.apperance);
|
||||
window.draw_cube(player.pos, 0.5, 0.5, 0.5, player.apperance);
|
||||
}
|
||||
|
||||
rl.end_mode_3d();
|
||||
window.end_mode_3d();
|
||||
|
||||
rl.end_drawing();
|
||||
window.end_drawing();
|
||||
}
|
||||
|
||||
me.logout();
|
||||
close_window(); ! Close window and OpenGL context
|
||||
window.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,46 @@
|
|||
type Vec {
|
||||
init(f32 x, f32 y, f32 z) {
|
||||
set this.x to x;
|
||||
set this.y to y;
|
||||
set this.z to z;
|
||||
type Vec3 {
|
||||
init(x real, y real, z real) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
|
||||
type Color {
|
||||
init(i8 r, i8 g, i8 b) {
|
||||
set this.r to r;
|
||||
set this.g to g;
|
||||
set this.b to b;
|
||||
init(r i8, g i8, b i8) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
|
||||
type Camera {
|
||||
init(pos Vec3, look Vec3) {
|
||||
this.setting = "CAMERA_PERSPECTIVE";
|
||||
this.pov = 45.0;
|
||||
this.up = Vec3(0.0, 1.0, 0.0);
|
||||
this.pos = pos;
|
||||
this.look = look;
|
||||
}
|
||||
}
|
||||
|
||||
type Player {
|
||||
init (9p server, str username, Vec pos, Color color) {
|
||||
set this.server to server;
|
||||
set this.username to username;
|
||||
set this.pos to pos;
|
||||
set this.color to color;
|
||||
init (username str, pos Vec3, color Color) {
|
||||
this.server = Tunnel("localhost:25565");
|
||||
this.username = username;
|
||||
this.pos = pos;
|
||||
this.color = color;
|
||||
this.camera = Camera(
|
||||
Vec3(this.pos.x + 10.0,
|
||||
this.pos.y + 10.0,
|
||||
this.pos.z),
|
||||
this.pos
|
||||
);
|
||||
}
|
||||
|
||||
login (str password) Player[] {
|
||||
this.server.auth(this.username, password);
|
||||
set this.players to server.open("players");
|
||||
login (password str) Player[] {
|
||||
this.server.attach(this.username, password);
|
||||
this.players = server.open("players");
|
||||
return players.read();
|
||||
}
|
||||
|
||||
|
@ -32,6 +48,30 @@ type Player {
|
|||
this.players.flush();
|
||||
this.server.clunk();
|
||||
}
|
||||
|
||||
update() {
|
||||
if (key_down(KEY_RIGHT)) {
|
||||
this.pos.x = this.pos.x + 0.2;
|
||||
this.server.write(Command(this.username, KEY_RIGHT))
|
||||
}
|
||||
|
||||
if (key_down(KEY_LEFT)) {
|
||||
this.pos.x = this.pos.x - 0.2;
|
||||
this.server.write(Command(this.username, KEY_LEFT))
|
||||
}
|
||||
|
||||
if (key_down(KEY_DOWN)) {
|
||||
this.pos.z = this.pos.z + 0.2;
|
||||
this.server.write(Command(this.username, KEY_DOWN))
|
||||
}
|
||||
|
||||
if (key_down(KEY_UP)) {
|
||||
this.pos.z = this.pos.z - 0.2;
|
||||
this.server.write(Command(this.username, KEY_UP))
|
||||
}
|
||||
this.camera.sync();
|
||||
}
|
||||
}
|
||||
|
||||
const purple is Color(255, 255, 0);
|
||||
const PURPLE is Color(255, 255, 0);
|
||||
const WHITE is Color(0, 0, 0);
|
||||
|
|
|
@ -1,75 +1,6 @@
|
|||
use "common.ztl";
|
||||
|
||||
fn main (i32 argc, str[] argv) i32 {
|
||||
set s to 9p (
|
||||
version,
|
||||
auth,
|
||||
error,
|
||||
flush,
|
||||
attach,
|
||||
walk,
|
||||
open,
|
||||
create,
|
||||
read,
|
||||
write,
|
||||
clunk,
|
||||
remove,
|
||||
stat,
|
||||
);
|
||||
|
||||
s.host("0.0.0.0:25565");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fn version(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn auth(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn error(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn flush(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn attach(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn walk(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn open(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn create(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn read(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn write(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn clunk(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn remove(9pmsg m) {
|
||||
|
||||
}
|
||||
|
||||
fn stat(9pmsg m) {
|
||||
|
||||
fn main (argc i32, argv str[]) i32 {
|
||||
let s = Server("0.0.0.0:25565");
|
||||
return s.start();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue