all: C++ compiler support
parent
857276e81f
commit
9a237c3e82
|
@ -273,3 +273,21 @@ jobs:
|
||||||
run: make
|
run: make
|
||||||
- name: Check docs line length
|
- name: Check docs line length
|
||||||
run: ./v run cmd/tools/check-md.v doc/docs.md CHANGELOG.md
|
run: ./v run cmd/tools/check-md.v doc/docs.md CHANGELOG.md
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ubuntu-c-plus-plus:
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install dependencies
|
||||||
|
run: sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list; sudo apt-get update; sudo apt-get install --quiet -y postgresql libpq-dev libglfw3 libglfw3-dev libfreetype6-dev libssl-dev sqlite3 libsqlite3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev valgrind g++-9
|
||||||
|
- name: Build V
|
||||||
|
run: make -j4
|
||||||
|
- name: g++ version
|
||||||
|
run: g++-9 --version
|
||||||
|
- name: Running tests with g++
|
||||||
|
run: ./v -cc g++-9 test-fixed
|
||||||
|
- name: V self compilation with g++
|
||||||
|
run: ./v -cc g++-9 -o v2 cmd/v && ./v2 -cc g++-9 -o v3 cmd/v
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@ const (
|
||||||
|
|
||||||
struct BenchedTests {
|
struct BenchedTests {
|
||||||
mut:
|
mut:
|
||||||
|
bench benchmark.Benchmark
|
||||||
oks int
|
oks int
|
||||||
fails int
|
fails int
|
||||||
test_suit_file string
|
test_suit_file string
|
||||||
step_func_name string
|
step_func_name string
|
||||||
bench benchmark.Benchmark
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -55,15 +55,15 @@ const (
|
||||||
pub struct Benchmark {
|
pub struct Benchmark {
|
||||||
pub mut:
|
pub mut:
|
||||||
bench_timer time.StopWatch
|
bench_timer time.StopWatch
|
||||||
|
verbose bool
|
||||||
|
no_cstep bool
|
||||||
step_timer time.StopWatch
|
step_timer time.StopWatch
|
||||||
ntotal int
|
ntotal int
|
||||||
nok int
|
nok int
|
||||||
nfail int
|
nfail int
|
||||||
nskip int
|
nskip int
|
||||||
verbose bool
|
|
||||||
nexpected_steps int
|
nexpected_steps int
|
||||||
cstep int
|
cstep int
|
||||||
no_cstep bool
|
|
||||||
bok string
|
bok string
|
||||||
bfail string
|
bfail string
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,10 @@ pub mut:
|
||||||
fn __new_array(mylen int, cap int, elm_size int) array {
|
fn __new_array(mylen int, cap int, elm_size int) array {
|
||||||
cap_ := if cap < mylen { mylen } else { cap }
|
cap_ := if cap < mylen { mylen } else { cap }
|
||||||
arr := array{
|
arr := array{
|
||||||
len: mylen
|
|
||||||
cap: cap_
|
|
||||||
element_size: elm_size
|
element_size: elm_size
|
||||||
data: vcalloc(cap_ * elm_size)
|
data: vcalloc(cap_ * elm_size)
|
||||||
|
len: mylen
|
||||||
|
cap: cap_
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,10 @@ fn __new_array(mylen int, cap int, elm_size int) array {
|
||||||
fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array {
|
fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array {
|
||||||
cap_ := if cap < mylen { mylen } else { cap }
|
cap_ := if cap < mylen { mylen } else { cap }
|
||||||
arr := array{
|
arr := array{
|
||||||
len: mylen
|
|
||||||
cap: cap_
|
|
||||||
element_size: elm_size
|
element_size: elm_size
|
||||||
data: vcalloc(cap_ * elm_size)
|
data: vcalloc(cap_ * elm_size)
|
||||||
|
len: mylen
|
||||||
|
cap: cap_
|
||||||
}
|
}
|
||||||
if val != 0 {
|
if val != 0 {
|
||||||
for i in 0..arr.len {
|
for i in 0..arr.len {
|
||||||
|
@ -48,10 +48,10 @@ fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array {
|
||||||
cap_ := if cap < len { len } else { cap }
|
cap_ := if cap < len { len } else { cap }
|
||||||
|
|
||||||
arr := array{
|
arr := array{
|
||||||
len: len
|
|
||||||
cap: cap_
|
|
||||||
element_size: elm_size
|
element_size: elm_size
|
||||||
data: vcalloc(cap_ * elm_size)
|
data: vcalloc(cap_ * elm_size)
|
||||||
|
len: len
|
||||||
|
cap: cap_
|
||||||
}
|
}
|
||||||
// TODO Write all memory functions (like memcpy) in V
|
// TODO Write all memory functions (like memcpy) in V
|
||||||
C.memcpy(arr.data, c_array, len * elm_size)
|
C.memcpy(arr.data, c_array, len * elm_size)
|
||||||
|
@ -61,10 +61,10 @@ fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array {
|
||||||
// Private function, used by V (`nums := [1, 2, 3] !`)
|
// Private function, used by V (`nums := [1, 2, 3] !`)
|
||||||
fn new_array_from_c_array_no_alloc(len, cap, elm_size int, c_array voidptr) array {
|
fn new_array_from_c_array_no_alloc(len, cap, elm_size int, c_array voidptr) array {
|
||||||
arr := array{
|
arr := array{
|
||||||
len: len
|
|
||||||
cap: cap
|
|
||||||
element_size: elm_size
|
element_size: elm_size
|
||||||
data: c_array
|
data: c_array
|
||||||
|
len: len
|
||||||
|
cap: cap
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
@ -98,10 +98,10 @@ pub fn (a array) repeat(count int) array {
|
||||||
size = a.element_size
|
size = a.element_size
|
||||||
}
|
}
|
||||||
arr := array{
|
arr := array{
|
||||||
len: count * a.len
|
|
||||||
cap: count * a.len
|
|
||||||
element_size: a.element_size
|
element_size: a.element_size
|
||||||
data: vcalloc(size)
|
data: vcalloc(size)
|
||||||
|
len: count * a.len
|
||||||
|
cap: count * a.len
|
||||||
}
|
}
|
||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
C.memcpy(byteptr(arr.data) + i * a.len * a.element_size, byteptr(a.data), a.len * a.element_size)
|
C.memcpy(byteptr(arr.data) + i * a.len * a.element_size, byteptr(a.data), a.len * a.element_size)
|
||||||
|
@ -241,10 +241,10 @@ pub fn (a &array) clone() array {
|
||||||
size++
|
size++
|
||||||
}
|
}
|
||||||
arr := array{
|
arr := array{
|
||||||
len: a.len
|
|
||||||
cap: a.cap
|
|
||||||
element_size: a.element_size
|
element_size: a.element_size
|
||||||
data: vcalloc(size)
|
data: vcalloc(size)
|
||||||
|
len: a.len
|
||||||
|
cap: a.cap
|
||||||
}
|
}
|
||||||
C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size)
|
C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size)
|
||||||
return arr
|
return arr
|
||||||
|
@ -312,10 +312,10 @@ pub fn (a array) reverse() array {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
arr := array{
|
arr := array{
|
||||||
len: a.len
|
|
||||||
cap: a.cap
|
|
||||||
element_size: a.element_size
|
element_size: a.element_size
|
||||||
data: vcalloc(a.cap * a.element_size)
|
data: vcalloc(a.cap * a.element_size)
|
||||||
|
len: a.len
|
||||||
|
cap: a.cap
|
||||||
}
|
}
|
||||||
for i in 0..a.len {
|
for i in 0..a.len {
|
||||||
//C.memcpy(arr.data + i * arr.element_size, &a[a.len - 1 - i], arr.element_size)
|
//C.memcpy(arr.data + i * arr.element_size, &a[a.len - 1 - i], arr.element_size)
|
||||||
|
|
|
@ -116,7 +116,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
|
||||||
buf := [1000]byte
|
buf := [1000]byte
|
||||||
mut output := ''
|
mut output := ''
|
||||||
for C.fgets(charptr(buf), 1000, f) != 0 {
|
for C.fgets(charptr(buf), 1000, f) != 0 {
|
||||||
output += tos(buf, vstrlen(buf))
|
output += tos(byteptr(buf), vstrlen(byteptr(buf)))
|
||||||
}
|
}
|
||||||
output = output.trim_space() + ':'
|
output = output.trim_space() + ':'
|
||||||
if C.pclose(f) != 0 {
|
if C.pclose(f) != 0 {
|
||||||
|
|
|
@ -12,7 +12,7 @@ fn C.free(ptr voidptr)
|
||||||
fn C.exit(code int)
|
fn C.exit(code int)
|
||||||
|
|
||||||
|
|
||||||
fn C.qsort(voidptr, int, int, voidptr)
|
fn C.qsort(voidptr, int, int, qsort_callback_func)
|
||||||
|
|
||||||
|
|
||||||
fn C.sprintf(a ...voidptr) int
|
fn C.sprintf(a ...voidptr) int
|
||||||
|
|
|
@ -383,8 +383,8 @@ pub fn (c rune) str() string {
|
||||||
|
|
||||||
pub fn (c byte) str() string {
|
pub fn (c byte) str() string {
|
||||||
mut str := string{
|
mut str := string{
|
||||||
len: 1
|
|
||||||
str: malloc(2)
|
str: malloc(2)
|
||||||
|
len: 1
|
||||||
}
|
}
|
||||||
str.str[0] = c
|
str.str[0] = c
|
||||||
str.str[1] = `\0`
|
str.str[1] = `\0`
|
||||||
|
|
|
@ -4,21 +4,21 @@
|
||||||
module builtin
|
module builtin
|
||||||
/*
|
/*
|
||||||
struct Option2<T> {
|
struct Option2<T> {
|
||||||
data T
|
|
||||||
error string
|
|
||||||
ecode int
|
|
||||||
ok bool
|
ok bool
|
||||||
is_none bool
|
is_none bool
|
||||||
|
error string
|
||||||
|
ecode int
|
||||||
|
data T
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
struct Option {
|
struct Option {
|
||||||
data [400]byte
|
|
||||||
error string
|
|
||||||
ecode int
|
|
||||||
ok bool
|
ok bool
|
||||||
is_none bool
|
is_none bool
|
||||||
|
error string
|
||||||
|
ecode int
|
||||||
|
data [400]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (o Option) str() string {
|
pub fn (o Option) str() string {
|
||||||
|
@ -46,18 +46,23 @@ fn opt_ok(data voidptr, size int) Option {
|
||||||
// used internally when returning `none`
|
// used internally when returning `none`
|
||||||
fn opt_none() Option {
|
fn opt_none() Option {
|
||||||
return Option{
|
return Option{
|
||||||
|
ok: false
|
||||||
is_none: true
|
is_none: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error(s string) Option {
|
pub fn error(s string) Option {
|
||||||
return Option{
|
return Option{
|
||||||
|
ok: false
|
||||||
|
is_none: false
|
||||||
error: s
|
error: s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error_with_code(s string, code int) Option {
|
pub fn error_with_code(s string, code int) Option {
|
||||||
return Option{
|
return Option{
|
||||||
|
ok: false
|
||||||
|
is_none: false
|
||||||
error: s
|
error: s
|
||||||
ecode: code
|
ecode: code
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,10 @@ pub mut:
|
||||||
|
|
||||||
struct mapnode {
|
struct mapnode {
|
||||||
mut:
|
mut:
|
||||||
keys [11]string // TODO: Should use `max_size`
|
|
||||||
values [11]voidptr // TODO: Should use `max_size`
|
|
||||||
children &voidptr
|
children &voidptr
|
||||||
size int
|
size int
|
||||||
|
keys [11]string // TODO: Should use `max_size`
|
||||||
|
values [11]voidptr // TODO: Should use `max_size`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_sorted_map(n, value_bytes int) SortedMap { // TODO: Remove `n`
|
fn new_sorted_map(n, value_bytes int) SortedMap { // TODO: Remove `n`
|
||||||
|
|
|
@ -122,8 +122,8 @@ fn (a string) clone_static() string {
|
||||||
|
|
||||||
pub fn (a string) clone() string {
|
pub fn (a string) clone() string {
|
||||||
mut b := string{
|
mut b := string{
|
||||||
len: a.len
|
|
||||||
str: malloc(a.len + 1)
|
str: malloc(a.len + 1)
|
||||||
|
len: a.len
|
||||||
}
|
}
|
||||||
for i in 0..a.len {
|
for i in 0..a.len {
|
||||||
b.str[i] = a.str[i]
|
b.str[i] = a.str[i]
|
||||||
|
@ -399,8 +399,8 @@ fn (s string) ge(a string) bool {
|
||||||
fn (s string) add(a string) string {
|
fn (s string) add(a string) string {
|
||||||
new_len := a.len + s.len
|
new_len := a.len + s.len
|
||||||
mut res := string{
|
mut res := string{
|
||||||
len: new_len
|
|
||||||
str: malloc(new_len + 1)
|
str: malloc(new_len + 1)
|
||||||
|
len: new_len
|
||||||
}
|
}
|
||||||
for j in 0..s.len {
|
for j in 0..s.len {
|
||||||
res.str[j] = s.str[j]
|
res.str[j] = s.str[j]
|
||||||
|
@ -537,8 +537,8 @@ pub fn (s string) substr(start, end int) string {
|
||||||
}
|
}
|
||||||
len := end - start
|
len := end - start
|
||||||
mut res := string{
|
mut res := string{
|
||||||
len: len
|
|
||||||
str: malloc(len + 1)
|
str: malloc(len + 1)
|
||||||
|
len: len
|
||||||
}
|
}
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
res.str[i] = s.str[start + i]
|
res.str[i] = s.str[start + i]
|
||||||
|
@ -1284,8 +1284,8 @@ pub fn (s string) reverse() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
mut res := string{
|
mut res := string{
|
||||||
len: s.len
|
|
||||||
str: malloc(s.len)
|
str: malloc(s.len)
|
||||||
|
len: s.len
|
||||||
}
|
}
|
||||||
for i := s.len - 1; i >= 0; i-- {
|
for i := s.len - 1; i >= 0; i-- {
|
||||||
res.str[s.len - i - 1] = s[i]
|
res.str[s.len - i - 1] = s[i]
|
||||||
|
|
|
@ -10,7 +10,8 @@ import math
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
// X11
|
// X11
|
||||||
struct C.Display{}
|
[typedef]
|
||||||
|
struct C.Display
|
||||||
|
|
||||||
[typedef]
|
[typedef]
|
||||||
struct C.Atom
|
struct C.Atom
|
||||||
|
@ -33,7 +34,7 @@ fn C.XCreateSimpleWindow(d &Display, root C.Window, x int, y int, width u32, hei
|
||||||
fn C.XOpenDisplay(name byteptr) &C.Display
|
fn C.XOpenDisplay(name byteptr) &C.Display
|
||||||
fn C.XConvertSelection(d &Display, selection C.Atom, target C.Atom, property C.Atom, requestor Window, time int) int
|
fn C.XConvertSelection(d &Display, selection C.Atom, target C.Atom, property C.Atom, requestor Window, time int) int
|
||||||
fn C.XSync(d &Display, discard int) int
|
fn C.XSync(d &Display, discard int) int
|
||||||
fn C.XGetWindowProperty(d &Display, w Window, property C.Atom, offset i64, length i64, delete int, req_type C.Atom, actual_type_return &C.Atom, actual_format_return &int, nitems &i64, bytes_after_return &i64, prop_return &byteptr) int
|
fn C.XGetWindowProperty(d &Display, w Window, property C.Atom, offset i64, length i64, delete int, req_type C.Atom, actual_type_return &C.Atom, actual_format_return &int, nitems &u64, bytes_after_return &u64, prop_return &byteptr) int
|
||||||
fn C.XDeleteProperty(d &Display, w Window, property C.Atom) int
|
fn C.XDeleteProperty(d &Display, w Window, property C.Atom) int
|
||||||
fn C.DefaultScreen() int
|
fn C.DefaultScreen() int
|
||||||
fn C.RootWindow() voidptr
|
fn C.RootWindow() voidptr
|
||||||
|
@ -46,10 +47,10 @@ fn todo_del(){}
|
||||||
[typedef]
|
[typedef]
|
||||||
struct C.XSelectionRequestEvent{
|
struct C.XSelectionRequestEvent{
|
||||||
mut:
|
mut:
|
||||||
selection C.Atom
|
|
||||||
display &C.Display /* Display the event was read from */
|
display &C.Display /* Display the event was read from */
|
||||||
owner C.Window
|
owner C.Window
|
||||||
requestor C.Window
|
requestor C.Window
|
||||||
|
selection C.Atom
|
||||||
target C.Atom
|
target C.Atom
|
||||||
property C.Atom
|
property C.Atom
|
||||||
time int
|
time int
|
||||||
|
@ -59,9 +60,9 @@ struct C.XSelectionRequestEvent{
|
||||||
struct C.XSelectionEvent{
|
struct C.XSelectionEvent{
|
||||||
mut:
|
mut:
|
||||||
@type int
|
@type int
|
||||||
selection C.Atom
|
|
||||||
display &C.Display /* Display the event was read from */
|
display &C.Display /* Display the event was read from */
|
||||||
requestor C.Window
|
requestor C.Window
|
||||||
|
selection C.Atom
|
||||||
target C.Atom
|
target C.Atom
|
||||||
property C.Atom
|
property C.Atom
|
||||||
time int
|
time int
|
||||||
|
@ -81,13 +82,13 @@ struct C.XDestroyWindowEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
[typedef]
|
[typedef]
|
||||||
struct C.XEvent{
|
union C.XEvent{
|
||||||
mut:
|
mut:
|
||||||
@type int
|
@type int
|
||||||
|
xdestroywindow C.XDestroyWindowEvent
|
||||||
|
xselectionclear C.XSelectionClearEvent
|
||||||
xselectionrequest C.XSelectionRequestEvent
|
xselectionrequest C.XSelectionRequestEvent
|
||||||
xselection C.XSelectionEvent
|
xselection C.XSelectionEvent
|
||||||
xselectionclear C.XSelectionClearEvent
|
|
||||||
xdestroywindow C.XDestroyWindowEvent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -287,7 +288,7 @@ fn (mut cb Clipboard) start_listener(){
|
||||||
if !cb.transmit_selection(&xse) {
|
if !cb.transmit_selection(&xse) {
|
||||||
xse.property = new_atom(C.None)
|
xse.property = new_atom(C.None)
|
||||||
}
|
}
|
||||||
C.XSendEvent(cb.display, xse.requestor, 0, C.PropertyChangeMask, &xse)
|
C.XSendEvent(cb.display, xse.requestor, 0, C.PropertyChangeMask, voidptr(&xse))
|
||||||
C.XFlush(cb.display)
|
C.XFlush(cb.display)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,8 +341,8 @@ fn (mut cb Clipboard) intern_atoms(){
|
||||||
fn read_property(d &C.Display, w C.Window, p C.Atom) Property {
|
fn read_property(d &C.Display, w C.Window, p C.Atom) Property {
|
||||||
actual_type := C.Atom(0)
|
actual_type := C.Atom(0)
|
||||||
actual_format := 0
|
actual_format := 0
|
||||||
nitems := 0
|
nitems := u64(0)
|
||||||
bytes_after := 0
|
bytes_after := u64(0)
|
||||||
ret := byteptr(0)
|
ret := byteptr(0)
|
||||||
mut read_bytes := 1024
|
mut read_bytes := 1024
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -75,6 +75,7 @@ pub fn (af []Flag) str() string {
|
||||||
pub struct FlagParser {
|
pub struct FlagParser {
|
||||||
pub mut:
|
pub mut:
|
||||||
args []string // the arguments to be parsed
|
args []string // the arguments to be parsed
|
||||||
|
max_free_args int
|
||||||
flags []Flag // registered flags
|
flags []Flag // registered flags
|
||||||
|
|
||||||
application_name string
|
application_name string
|
||||||
|
@ -82,7 +83,6 @@ pub struct FlagParser {
|
||||||
application_description string
|
application_description string
|
||||||
|
|
||||||
min_free_args int
|
min_free_args int
|
||||||
max_free_args int
|
|
||||||
args_description string
|
args_description string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub fn sum64_string(key string, seed u64) u64 {
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn sum64(key []byte, seed u64) u64 {
|
pub fn sum64(key []byte, seed u64) u64 {
|
||||||
return wyhash64(key.data, u64(key.len), seed)
|
return wyhash64(byteptr(key.data), u64(key.len), seed)
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
|
|
|
@ -6,10 +6,13 @@ module big
|
||||||
#flag @VROOT/thirdparty/bignum/bn.o
|
#flag @VROOT/thirdparty/bignum/bn.o
|
||||||
#include "bn.h"
|
#include "bn.h"
|
||||||
|
|
||||||
pub struct Number {
|
[typedef]
|
||||||
|
struct C.bn {
|
||||||
array [32]u32
|
array [32]u32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Number = C.bn
|
||||||
|
|
||||||
fn C.bignum_init( n &Number )
|
fn C.bignum_init( n &Number )
|
||||||
fn C.bignum_from_int( n &Number, i u64 )
|
fn C.bignum_from_int( n &Number, i u64 )
|
||||||
fn C.bignum_to_int( n &Number ) int
|
fn C.bignum_to_int( n &Number ) int
|
||||||
|
|
|
@ -18,8 +18,8 @@ import strings
|
||||||
#flag darwin -I/usr/local/opt/openssl/include
|
#flag darwin -I/usr/local/opt/openssl/include
|
||||||
#flag darwin -L/usr/local/opt/openssl/lib
|
#flag darwin -L/usr/local/opt/openssl/lib
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
struct C.SSL {
|
|
||||||
}
|
struct C.ssl_st
|
||||||
|
|
||||||
fn C.SSL_library_init()
|
fn C.SSL_library_init()
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ fn (req &Request) ssl_do(port int, method, host_name, path string) ?Response {
|
||||||
res = C.BIO_set_conn_hostname(web, addr.str)
|
res = C.BIO_set_conn_hostname(web, addr.str)
|
||||||
if res != 1 {
|
if res != 1 {
|
||||||
}
|
}
|
||||||
ssl := &C.SSL(0)
|
ssl := &C.ssl_st(0)
|
||||||
C.BIO_get_ssl(web, &ssl)
|
C.BIO_get_ssl(web, &ssl)
|
||||||
if isnil(ssl) {
|
if isnil(ssl) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,11 @@ pub fn hostname() ?string {
|
||||||
mut name := [256]byte
|
mut name := [256]byte
|
||||||
// https://www.ietf.org/rfc/rfc1035.txt
|
// https://www.ietf.org/rfc/rfc1035.txt
|
||||||
// The host name is returned as a null-terminated string.
|
// The host name is returned as a null-terminated string.
|
||||||
res := C.gethostname(&name, 256)
|
namebp := byteptr(name)
|
||||||
|
res := C.gethostname(namebp, 256)
|
||||||
if res != 0 {
|
if res != 0 {
|
||||||
return error('net.hostname: failed with $res')
|
return error('net.hostname: failed with $res')
|
||||||
}
|
}
|
||||||
return tos_clone(name)
|
return tos_clone(namebp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@ mut:
|
||||||
s_addr int
|
s_addr int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct C.sockaddr {
|
||||||
|
}
|
||||||
|
|
||||||
struct C.sockaddr_in {
|
struct C.sockaddr_in {
|
||||||
mut:
|
mut:
|
||||||
sin_family int
|
sin_family int
|
||||||
|
@ -108,7 +111,9 @@ pub fn (s Socket) bind(port int) ?int {
|
||||||
addr.sin_port = C.htons(port)
|
addr.sin_port = C.htons(port)
|
||||||
addr.sin_addr.s_addr = C.htonl(C.INADDR_ANY)
|
addr.sin_addr.s_addr = C.htonl(C.INADDR_ANY)
|
||||||
size := 16 // sizeof(C.sockaddr_in)
|
size := 16 // sizeof(C.sockaddr_in)
|
||||||
res := C.bind(s.sockfd, &addr, size)
|
tmp := voidptr(&addr)
|
||||||
|
skaddr := &C.sockaddr(tmp)
|
||||||
|
res := C.bind(s.sockfd, skaddr, size)
|
||||||
if res < 0 {
|
if res < 0 {
|
||||||
return error('net.bind: failed with $res')
|
return error('net.bind: failed with $res')
|
||||||
}
|
}
|
||||||
|
@ -165,7 +170,9 @@ pub fn (s Socket) accept() ?Socket {
|
||||||
}
|
}
|
||||||
addr := C.sockaddr_storage{}
|
addr := C.sockaddr_storage{}
|
||||||
size := 128 // sizeof(sockaddr_storage)
|
size := 128 // sizeof(sockaddr_storage)
|
||||||
sockfd := C.accept(s.sockfd, &addr, &size)
|
tmp := voidptr(&addr)
|
||||||
|
skaddr := &C.sockaddr(tmp)
|
||||||
|
sockfd := C.accept(s.sockfd, skaddr, &size)
|
||||||
if sockfd < 0 {
|
if sockfd < 0 {
|
||||||
return error('net.accept: failed with $sockfd')
|
return error('net.accept: failed with $sockfd')
|
||||||
}
|
}
|
||||||
|
@ -255,8 +262,8 @@ pub fn (s Socket) cread(buffer byteptr, buffersize int) int {
|
||||||
|
|
||||||
// Receive a message from the socket, and place it in a preallocated buffer buf,
|
// Receive a message from the socket, and place it in a preallocated buffer buf,
|
||||||
// with maximum message size bufsize. Returns the length of the received message.
|
// with maximum message size bufsize. Returns the length of the received message.
|
||||||
pub fn (s Socket) crecv(buffer byteptr, buffersize int) int {
|
pub fn (s Socket) crecv(buffer voidptr, buffersize int) int {
|
||||||
return C.recv(s.sockfd, buffer, buffersize, 0)
|
return C.recv(s.sockfd, byteptr(buffer), buffersize, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdown and close socket
|
// shutdown and close socket
|
||||||
|
@ -325,7 +332,8 @@ pub fn (s Socket) read_line() string {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line = tos_clone(buf)
|
bufbp := byteptr(buf)
|
||||||
|
line = tos_clone(bufbp)
|
||||||
if eol_idx > 0 {
|
if eol_idx > 0 {
|
||||||
// At this point, we are sure that recv returned valid data,
|
// At this point, we are sure that recv returned valid data,
|
||||||
// that contains *at least* one line.
|
// that contains *at least* one line.
|
||||||
|
@ -357,7 +365,8 @@ pub fn (s Socket) read_all() string {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
res += tos_clone(buf)
|
bufbp := byteptr(buf)
|
||||||
|
res += tos_clone(bufbp)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -365,6 +374,8 @@ pub fn (s Socket) read_all() string {
|
||||||
pub fn (s Socket) get_port() int {
|
pub fn (s Socket) get_port() int {
|
||||||
mut addr := C.sockaddr_in{}
|
mut addr := C.sockaddr_in{}
|
||||||
size := 16 // sizeof(sockaddr_in)
|
size := 16 // sizeof(sockaddr_in)
|
||||||
C.getsockname(s.sockfd, &addr, &size)
|
tmp := voidptr(&addr)
|
||||||
|
skaddr := &C.sockaddr(tmp)
|
||||||
|
C.getsockname(s.sockfd, skaddr, &size)
|
||||||
return C.ntohs(addr.sin_port)
|
return C.ntohs(addr.sin_port)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ pub fn open(path string) ?File {
|
||||||
*/
|
*/
|
||||||
file := File{
|
file := File{
|
||||||
cfile: C.fopen(charptr(path.str), 'rb')
|
cfile: C.fopen(charptr(path.str), 'rb')
|
||||||
|
fd: 0
|
||||||
opened: true
|
opened: true
|
||||||
}
|
}
|
||||||
if isnil(file.cfile) {
|
if isnil(file.cfile) {
|
||||||
|
@ -119,6 +120,7 @@ pub fn create(path string) ?File {
|
||||||
*/
|
*/
|
||||||
file := File{
|
file := File{
|
||||||
cfile: C.fopen(charptr(path.str), 'wb')
|
cfile: C.fopen(charptr(path.str), 'wb')
|
||||||
|
fd: 0
|
||||||
opened: true
|
opened: true
|
||||||
}
|
}
|
||||||
if isnil(file.cfile) {
|
if isnil(file.cfile) {
|
||||||
|
@ -207,7 +209,8 @@ pub fn exec(cmd string) ?Result {
|
||||||
buf := [4096]byte
|
buf := [4096]byte
|
||||||
mut res := strings.new_builder(1024)
|
mut res := strings.new_builder(1024)
|
||||||
for C.fgets(charptr(buf), 4096, f) != 0 {
|
for C.fgets(charptr(buf), 4096, f) != 0 {
|
||||||
res.write_bytes( buf, vstrlen(buf) )
|
bufbp := byteptr(buf)
|
||||||
|
res.write_bytes( bufbp, vstrlen(bufbp) )
|
||||||
}
|
}
|
||||||
soutput := res.str().trim_space()
|
soutput := res.str().trim_space()
|
||||||
//res.free()
|
//res.free()
|
||||||
|
@ -216,8 +219,8 @@ pub fn exec(cmd string) ?Result {
|
||||||
// return error(res)
|
// return error(res)
|
||||||
// }
|
// }
|
||||||
return Result{
|
return Result{
|
||||||
output: soutput
|
|
||||||
exit_code: exit_code
|
exit_code: exit_code
|
||||||
|
output: soutput
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -664,7 +664,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.write(format_dec(d1,{positive: positive, pad_ch: pad_ch, len0: len0, sign_flag: sign, allign: allign}))
|
res.write(format_dec(d1,{pad_ch: pad_ch, len0: len0, len1: 0, positive: positive, sign_flag: sign, allign: allign}))
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
|
@ -707,7 +707,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.write(format_dec(d1,{positive: positive, pad_ch: pad_ch, len0: len0, sign_flag: sign, allign: allign}))
|
res.write(format_dec(d1,{pad_ch: pad_ch, len0: len0, len1: 0, positive: positive, sign_flag: sign, allign: allign}))
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
|
@ -755,7 +755,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
||||||
s = s.to_upper()
|
s = s.to_upper()
|
||||||
}
|
}
|
||||||
|
|
||||||
res.write(format_str(s,{pad_ch: pad_ch, len0: len0, allign: allign}))
|
res.write(format_str(s,{pad_ch: pad_ch, len0: len0, len1: 0, positive: true, sign_flag: false, allign: allign}))
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
|
@ -767,7 +767,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
||||||
x := *(&f64(pt[p_index]))
|
x := *(&f64(pt[p_index]))
|
||||||
mut positive := x >= f64(0.0)
|
mut positive := x >= f64(0.0)
|
||||||
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
||||||
s := format_fl(f64(x), {positive: positive, pad_ch: pad_ch, len0: len0, len1: len1, sign_flag: sign, allign: allign})
|
s := format_fl(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign})
|
||||||
res.write(if ch == `F` {s.to_upper()} else {s})
|
res.write(if ch == `F` {s.to_upper()} else {s})
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
|
@ -778,7 +778,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
||||||
x := *(&f64(pt[p_index]))
|
x := *(&f64(pt[p_index]))
|
||||||
mut positive := x >= f64(0.0)
|
mut positive := x >= f64(0.0)
|
||||||
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
||||||
s := format_es(f64(x), {positive: positive, pad_ch: pad_ch, len0: len0, len1: len1, sign_flag: sign, allign: allign})
|
s := format_es(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign})
|
||||||
res.write(if ch == `E` {s.to_upper()} else {s})
|
res.write(if ch == `E` {s.to_upper()} else {s})
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
|
@ -793,10 +793,10 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
||||||
if tx < 999_999.0 && tx >= 0.00001 {
|
if tx < 999_999.0 && tx >= 0.00001 {
|
||||||
//println("Here g format_fl [$tx]")
|
//println("Here g format_fl [$tx]")
|
||||||
len1 = if len1 >= 0 { len1+1 } else { def_len1 }
|
len1 = if len1 >= 0 { len1+1 } else { def_len1 }
|
||||||
s = format_fl(x, {positive: positive, pad_ch: pad_ch, len0: len0, len1: len1, sign_flag: sign, allign: allign, rm_tail_zero: true})
|
s = format_fl(x, {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign, rm_tail_zero: true})
|
||||||
} else {
|
} else {
|
||||||
len1 = if len1 >= 0 { len1+1 } else { def_len1 }
|
len1 = if len1 >= 0 { len1+1 } else { def_len1 }
|
||||||
s = format_es(x, {positive: positive, pad_ch: pad_ch, len0: len0, len1: len1, sign_flag: sign, allign: allign, rm_tail_zero: true})
|
s = format_es(x, {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign, rm_tail_zero: true})
|
||||||
}
|
}
|
||||||
res.write(if ch == `G` {s.to_upper()} else {s})
|
res.write(if ch == `G` {s.to_upper()} else {s})
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
|
@ -809,7 +809,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
||||||
else if ch == `s` {
|
else if ch == `s` {
|
||||||
s1 := *(&string(pt[p_index]))
|
s1 := *(&string(pt[p_index]))
|
||||||
pad_ch = ` `
|
pad_ch = ` `
|
||||||
res.write(format_str(s1, {pad_ch: pad_ch, len0: len0, allign: allign}))
|
res.write(format_str(s1, {pad_ch: pad_ch, len0: len0, len1: 0, positive: true, sign_flag: false, allign: allign}))
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
|
|
|
@ -190,7 +190,7 @@ fn shift_right_128(v Uint128, shift int) u64 {
|
||||||
fn mul_shift_64(m u64, mul Uint128, shift int) u64 {
|
fn mul_shift_64(m u64, mul Uint128, shift int) u64 {
|
||||||
hihi, hilo := bits.mul_64(m, mul.hi)
|
hihi, hilo := bits.mul_64(m, mul.hi)
|
||||||
lohi, _ := bits.mul_64(m, mul.lo)
|
lohi, _ := bits.mul_64(m, mul.lo)
|
||||||
mut sum := Uint128{hi: hihi, lo: lohi + hilo}
|
mut sum := Uint128{lo: lohi + hilo,hi: hihi}
|
||||||
if sum.lo < lohi {
|
if sum.lo < lohi {
|
||||||
sum.hi++ // overflow
|
sum.hi++ // overflow
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ pub fn new_builder(initial_size int) Builder {
|
||||||
return Builder{
|
return Builder{
|
||||||
//buf: make(0, initial_size)
|
//buf: make(0, initial_size)
|
||||||
buf: []byte{cap: initial_size}
|
buf: []byte{cap: initial_size}
|
||||||
|
str_calls: 0
|
||||||
|
len: 0
|
||||||
initial_size: initial_size
|
initial_size: initial_size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_stopwatch() StopWatch {
|
pub fn new_stopwatch() StopWatch {
|
||||||
return StopWatch{start: time.sys_mono_now()}
|
return StopWatch{pause_time: 0, start: time.sys_mono_now(), end: 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
// start Starts the timer. If the timer was paused, restarts counting.
|
// start Starts the timer. If the timer was paused, restarts counting.
|
||||||
|
|
|
@ -76,23 +76,18 @@ pub enum FormatDelimiter {
|
||||||
no_delimiter
|
no_delimiter
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: C.time_t. works in v2
|
|
||||||
type time_t voidptr
|
|
||||||
|
|
||||||
pub struct C.timeval {
|
pub struct C.timeval {
|
||||||
tv_sec u64
|
tv_sec u64
|
||||||
tv_usec u64
|
tv_usec u64
|
||||||
}
|
}
|
||||||
|
|
||||||
fn C.localtime(int) &C.tm
|
fn C.localtime(t &C.time_t) &C.tm
|
||||||
|
fn C.time(t &C.time_t) C.time_t
|
||||||
fn C.time(int) time_t
|
|
||||||
|
|
||||||
// now returns current local time.
|
// now returns current local time.
|
||||||
pub fn now() Time {
|
pub fn now() Time {
|
||||||
t := C.time(0)
|
t := C.time(0)
|
||||||
mut now := &C.tm(0)
|
now := C.localtime(&t)
|
||||||
now = C.localtime(&t)
|
|
||||||
return convert_ctime(now)
|
return convert_ctime(now)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
module time
|
module time
|
||||||
|
|
||||||
struct C.tm {
|
struct C.tm {
|
||||||
tm_year int
|
|
||||||
tm_mon int
|
|
||||||
tm_mday int
|
|
||||||
tm_hour int
|
|
||||||
tm_min int
|
|
||||||
tm_sec int
|
tm_sec int
|
||||||
|
tm_min int
|
||||||
|
tm_hour int
|
||||||
|
tm_mday int
|
||||||
|
tm_mon int
|
||||||
|
tm_year int
|
||||||
}
|
}
|
||||||
|
|
||||||
fn C.timegm(&tm) time_t
|
fn C.timegm(&tm) time_t
|
||||||
|
|
|
@ -306,6 +306,11 @@ fn (mut v Builder) cc() {
|
||||||
// add all flags (-I -l -L etc) not .o files
|
// add all flags (-I -l -L etc) not .o files
|
||||||
a << cflags.c_options_without_object_files()
|
a << cflags.c_options_without_object_files()
|
||||||
a << libs
|
a << libs
|
||||||
|
// For C++ we must be very tolerant
|
||||||
|
if guessed_compiler.contains('++') {
|
||||||
|
a << '-fpermissive'
|
||||||
|
a << '-w'
|
||||||
|
}
|
||||||
if v.pref.use_cache {
|
if v.pref.use_cache {
|
||||||
//vexe := pref.vexe_path()
|
//vexe := pref.vexe_path()
|
||||||
|
|
||||||
|
@ -344,7 +349,7 @@ fn (mut v Builder) cc() {
|
||||||
if !v.pref.is_bare && v.pref.os == .js && os.user_os() == 'linux' {
|
if !v.pref.is_bare && v.pref.os == .js && os.user_os() == 'linux' {
|
||||||
linker_flags << '-lm'
|
linker_flags << '-lm'
|
||||||
}
|
}
|
||||||
args := a.join(' ') + linker_flags.join(' ')
|
args := a.join(' ') + ' ' + linker_flags.join(' ')
|
||||||
start:
|
start:
|
||||||
todo()
|
todo()
|
||||||
// TODO remove
|
// TODO remove
|
||||||
|
|
|
@ -37,7 +37,9 @@ const (
|
||||||
'void',
|
'void',
|
||||||
'volatile',
|
'volatile',
|
||||||
'while',
|
'while',
|
||||||
'new'
|
'new',
|
||||||
|
'namespace',
|
||||||
|
'typename'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -314,8 +316,14 @@ fn (mut g Gen) typ(t table.Type) string {
|
||||||
fn (g &Gen) base_type(t table.Type) string {
|
fn (g &Gen) base_type(t table.Type) string {
|
||||||
mut styp := g.cc_type(t)
|
mut styp := g.cc_type(t)
|
||||||
nr_muls := t.nr_muls()
|
nr_muls := t.nr_muls()
|
||||||
if nr_muls > 0 {
|
$if windows { // TODO: This is not really understood
|
||||||
styp += strings.repeat(`*`, nr_muls)
|
if nr_muls > 0 {
|
||||||
|
styp += strings.repeat(`*`, nr_muls)
|
||||||
|
}
|
||||||
|
} $else {
|
||||||
|
if nr_muls > 0 && !(t.idx() in [ table.byteptr_type_idx ]) {
|
||||||
|
styp += strings.repeat(`*`, nr_muls)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return styp
|
return styp
|
||||||
}
|
}
|
||||||
|
@ -363,7 +371,12 @@ typedef struct {
|
||||||
.alias {
|
.alias {
|
||||||
parent := &g.table.types[typ.parent_idx]
|
parent := &g.table.types[typ.parent_idx]
|
||||||
styp := typ.name.replace('.', '__')
|
styp := typ.name.replace('.', '__')
|
||||||
parent_styp := parent.name.replace('.', '__')
|
is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.`
|
||||||
|
parent_styp := if is_c_parent {
|
||||||
|
'struct ' + parent.name[2..].replace('.', '__')
|
||||||
|
} else {
|
||||||
|
parent.name.replace('.', '__')
|
||||||
|
}
|
||||||
g.definitions.writeln('typedef $parent_styp $styp;')
|
g.definitions.writeln('typedef $parent_styp $styp;')
|
||||||
}
|
}
|
||||||
.array {
|
.array {
|
||||||
|
@ -591,7 +604,13 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
// just remember `it`; main code will be generated in finish()
|
// just remember `it`; main code will be generated in finish()
|
||||||
g.fn_main = it
|
g.fn_main = it
|
||||||
} else {
|
} else {
|
||||||
|
if it.name == 'backtrace' || it.name == 'backtrace_symbols' || it.name == 'backtrace_symbols_fd' {
|
||||||
|
g.write('\n#ifndef __cplusplus\n')
|
||||||
|
}
|
||||||
g.gen_fn_decl(it)
|
g.gen_fn_decl(it)
|
||||||
|
if it.name == 'backtrace' || it.name == 'backtrace_symbols' || it.name == 'backtrace_symbols_fd' {
|
||||||
|
g.write('\n#endif\n')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g.fn_decl = keep_fn_decl
|
g.fn_decl = keep_fn_decl
|
||||||
if skip {
|
if skip {
|
||||||
|
@ -1210,9 +1229,9 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||||
// `string(x)` needs `tos()`, but not `&string(x)
|
// `string(x)` needs `tos()`, but not `&string(x)
|
||||||
// `tos(str, len)`, `tos2(str)`
|
// `tos(str, len)`, `tos2(str)`
|
||||||
if it.has_arg {
|
if it.has_arg {
|
||||||
g.write('tos(')
|
g.write('tos((byteptr)')
|
||||||
} else {
|
} else {
|
||||||
g.write('tos2(')
|
g.write('tos2((byteptr)')
|
||||||
}
|
}
|
||||||
g.expr(it.expr)
|
g.expr(it.expr)
|
||||||
expr_sym := g.table.get_type_symbol(it.expr_type)
|
expr_sym := g.table.get_type_symbol(it.expr_type)
|
||||||
|
@ -1286,17 +1305,17 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||||
value_typ_str := g.typ(it.value_type)
|
value_typ_str := g.typ(it.value_type)
|
||||||
size := it.vals.len
|
size := it.vals.len
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
g.write('new_map_init($size, sizeof($value_typ_str), (${key_typ_str}[$size]){')
|
g.write('new_map_init($size, sizeof($value_typ_str), _MOV((${key_typ_str}[$size]){')
|
||||||
for expr in it.keys {
|
for expr in it.keys {
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
g.write('}, (${value_typ_str}[$size]){')
|
g.write('}), _MOV((${value_typ_str}[$size]){')
|
||||||
for expr in it.vals {
|
for expr in it.vals {
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
g.write('})')
|
g.write('}))')
|
||||||
} else {
|
} else {
|
||||||
g.write('new_map_1(sizeof($value_typ_str))')
|
g.write('new_map_1(sizeof($value_typ_str))')
|
||||||
}
|
}
|
||||||
|
@ -1665,7 +1684,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||||
elem_type_str := g.typ(info.elem_type)
|
elem_type_str := g.typ(info.elem_type)
|
||||||
g.write('array_push(&')
|
g.write('array_push(&')
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.write(', &($elem_type_str[]){ ')
|
g.write(', _MOV(($elem_type_str[]){ ')
|
||||||
elem_sym := g.table.get_type_symbol(info.elem_type)
|
elem_sym := g.table.get_type_symbol(info.elem_type)
|
||||||
if elem_sym.kind == .interface_ && node.right_type != info.elem_type {
|
if elem_sym.kind == .interface_ && node.right_type != info.elem_type {
|
||||||
g.interface_call(node.right_type, info.elem_type)
|
g.interface_call(node.right_type, info.elem_type)
|
||||||
|
@ -1674,7 +1693,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||||
if elem_sym.kind == .interface_ && node.right_type != info.elem_type {
|
if elem_sym.kind == .interface_ && node.right_type != info.elem_type {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
g.write(' })')
|
g.write(' }))')
|
||||||
}
|
}
|
||||||
} else if (node.left_type == node.right_type) && node.left_type.is_float() && node.op in
|
} else if (node.left_type == node.right_type) && node.left_type.is_float() && node.op in
|
||||||
[.eq, .ne] {
|
[.eq, .ne] {
|
||||||
|
@ -1697,7 +1716,8 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
} else if node.op in [.plus, .minus, .mul, .div, .mod] && (left_sym.name[0].is_capital() ||
|
} else if node.op in [.plus, .minus, .mul, .div, .mod] && (left_sym.name[0].is_capital() ||
|
||||||
left_sym.name.contains('.')) && left_sym.kind != .alias {
|
left_sym.name.contains('.')) && left_sym.kind != .alias ||
|
||||||
|
left_sym.kind == .alias && (left_sym.info as table.Alias).is_c {
|
||||||
// !left_sym.is_number() {
|
// !left_sym.is_number() {
|
||||||
g.write(g.typ(node.left_type))
|
g.write(g.typ(node.left_type))
|
||||||
g.write('_')
|
g.write('_')
|
||||||
|
@ -2009,7 +2029,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if need_wrapper {
|
if need_wrapper {
|
||||||
g.write(', &($elem_type_str[]) { ')
|
g.write(', &($elem_type_str[]) { \n')
|
||||||
} else {
|
} else {
|
||||||
g.write(', &')
|
g.write(', &')
|
||||||
}
|
}
|
||||||
|
@ -2061,7 +2081,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
g.expr(node.index)
|
g.expr(node.index)
|
||||||
g.write(', &($elem_type_str[]) { ')
|
g.write(', &($elem_type_str[]) { \n')
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
g.write('(*($elem_type_str*)map_get2(')
|
g.write('(*($elem_type_str*)map_get2(')
|
||||||
|
@ -2075,7 +2095,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
g.expr(node.index)
|
g.expr(node.index)
|
||||||
g.write(', &($elem_type_str[]){ $zero }))')
|
g.write(', &($elem_type_str[]){ $zero }))\n')
|
||||||
}
|
}
|
||||||
} else if sym.kind == .string && !node.left_type.is_ptr() {
|
} else if sym.kind == .string && !node.left_type.is_ptr() {
|
||||||
g.write('string_at(')
|
g.write('string_at(')
|
||||||
|
@ -2237,9 +2257,18 @@ fn (mut g Gen) const_decl_init_later(name, val string, typ table.Type) {
|
||||||
g.inits.writeln('\t_const_$name = $val;')
|
g.inits.writeln('\t_const_$name = $val;')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) go_back_out(n int) {
|
||||||
|
g.out.go_back(n)
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
sym := g.table.get_type_symbol(struct_init.typ)
|
skip_init := ['strconv__ftoa__Uf32', 'strconv__ftoa__Uf64', 'strconv__Float64u', 'struct stat', 'struct addrinfo']
|
||||||
styp := g.typ(struct_init.typ)
|
styp := g.typ(struct_init.typ)
|
||||||
|
if styp in skip_init {
|
||||||
|
g.go_back_out(3)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sym := g.table.get_type_symbol(struct_init.typ)
|
||||||
is_amp := g.is_amp
|
is_amp := g.is_amp
|
||||||
g.is_amp = false // reset the flag immediately so that other struct inits in this expr are handled correctly
|
g.is_amp = false // reset the flag immediately so that other struct inits in this expr are handled correctly
|
||||||
if is_amp {
|
if is_amp {
|
||||||
|
@ -2249,7 +2278,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
g.writeln('($styp){')
|
g.writeln('($styp){')
|
||||||
}
|
}
|
||||||
// mut fields := []string{}
|
// mut fields := []string{}
|
||||||
mut inited_fields := []string{} // TODO this is done in checker, move to ast node
|
mut inited_fields := map[string]int // TODO this is done in checker, move to ast node
|
||||||
/*
|
/*
|
||||||
if struct_init.fields.len == 0 && struct_init.exprs.len > 0 {
|
if struct_init.fields.len == 0 && struct_init.exprs.len > 0 {
|
||||||
// Get fields for {a,b} short syntax. Fields array wasn't set in the parser.
|
// Get fields for {a,b} short syntax. Fields array wasn't set in the parser.
|
||||||
|
@ -2261,33 +2290,63 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// User set fields
|
// User set fields
|
||||||
for _, field in struct_init.fields {
|
mut initialized := false
|
||||||
field_name := c_name(field.name)
|
for i, field in struct_init.fields {
|
||||||
inited_fields << field.name
|
inited_fields[field.name] = i
|
||||||
g.write('\t.$field_name = ')
|
if sym.kind != .struct_ {
|
||||||
field_type_sym := g.table.get_type_symbol(field.typ)
|
field_name := c_name(field.name)
|
||||||
mut cloned := false
|
g.write('\t.$field_name = ')
|
||||||
if g.autofree && field_type_sym.kind in [.array, .string] {
|
field_type_sym := g.table.get_type_symbol(field.typ)
|
||||||
g.write('/*clone1*/')
|
mut cloned := false
|
||||||
if g.gen_clone_assignment(field.expr, field_type_sym, false) {
|
if g.autofree && field_type_sym.kind in [.array, .string] {
|
||||||
cloned = true
|
g.write('/*clone1*/')
|
||||||
|
if g.gen_clone_assignment(field.expr, field_type_sym, false) {
|
||||||
|
cloned = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if !cloned {
|
||||||
if !cloned {
|
if field.expected_type.is_ptr() && !field.typ.is_ptr() && !field.typ.is_number() {
|
||||||
if field.expected_type.is_ptr() && !field.typ.is_ptr() && !field.typ.is_number() {
|
g.write('/* autoref */&')
|
||||||
g.write('/* autoref */&')
|
}
|
||||||
|
g.expr_with_cast(field.expr, field.typ, field.expected_type)
|
||||||
}
|
}
|
||||||
g.expr_with_cast(field.expr, field.typ, field.expected_type)
|
g.writeln(',')
|
||||||
|
initialized = true
|
||||||
}
|
}
|
||||||
g.writeln(',')
|
|
||||||
}
|
}
|
||||||
// The rest of the fields are zeroed.
|
// The rest of the fields are zeroed.
|
||||||
mut nr_info_fields := 0
|
mut nr_info_fields := 0
|
||||||
if sym.kind == .struct_ {
|
if sym.kind == .struct_ {
|
||||||
info := sym.info as table.Struct
|
info := sym.info as table.Struct
|
||||||
|
if info.is_union && struct_init.fields.len > 1 {
|
||||||
|
verror('union must not have more than 1 initializer')
|
||||||
|
}
|
||||||
nr_info_fields = info.fields.len
|
nr_info_fields = info.fields.len
|
||||||
for field in info.fields {
|
for field in info.fields {
|
||||||
if field.name in inited_fields {
|
if field.name in inited_fields {
|
||||||
|
sfield := struct_init.fields[inited_fields[field.name]]
|
||||||
|
field_name := c_name(sfield.name)
|
||||||
|
g.write('\t.$field_name = ')
|
||||||
|
field_type_sym := g.table.get_type_symbol(sfield.typ)
|
||||||
|
mut cloned := false
|
||||||
|
if g.autofree && field_type_sym.kind in [.array, .string] {
|
||||||
|
g.write('/*clone1*/')
|
||||||
|
if g.gen_clone_assignment(sfield.expr, field_type_sym, false) {
|
||||||
|
cloned = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !cloned {
|
||||||
|
if sfield.expected_type.is_ptr() && !sfield.typ.is_ptr() && !sfield.typ.is_number() {
|
||||||
|
g.write('/* autoref */&')
|
||||||
|
}
|
||||||
|
g.expr_with_cast(sfield.expr, sfield.typ, sfield.expected_type)
|
||||||
|
}
|
||||||
|
g.writeln(',')
|
||||||
|
initialized = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if info.is_union {
|
||||||
|
// unions thould have exactly one explicit initializer
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if field.typ.flag_is(.optional) {
|
if field.typ.flag_is(.optional) {
|
||||||
|
@ -2302,11 +2361,12 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
g.write(g.type_default(field.typ))
|
g.write(g.type_default(field.typ))
|
||||||
}
|
}
|
||||||
g.writeln(',')
|
g.writeln(',')
|
||||||
|
initialized = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if struct_init.fields.len == 0 && info.fields.len == 0 {
|
// if struct_init.fields.len == 0 && info.fields.len == 0 {
|
||||||
if struct_init.fields.len == 0 && nr_info_fields == 0 {
|
if !initialized {
|
||||||
g.write('0')
|
g.write('\n#ifndef __cplusplus\n0\n#endif\n')
|
||||||
}
|
}
|
||||||
g.write('}')
|
g.write('}')
|
||||||
if is_amp {
|
if is_amp {
|
||||||
|
@ -2322,21 +2382,22 @@ fn (mut g Gen) assoc(node ast.Assoc) {
|
||||||
}
|
}
|
||||||
styp := g.typ(node.typ)
|
styp := g.typ(node.typ)
|
||||||
g.writeln('($styp){')
|
g.writeln('($styp){')
|
||||||
|
mut inited_fields := map[string]int
|
||||||
for i, field in node.fields {
|
for i, field in node.fields {
|
||||||
field_name := c_name(field)
|
inited_fields[field] = i
|
||||||
g.write('\t.$field_name = ')
|
|
||||||
g.expr(node.exprs[i])
|
|
||||||
g.writeln(', ')
|
|
||||||
}
|
}
|
||||||
// Copy the rest of the fields.
|
// Merge inited_fields in the rest of the fields.
|
||||||
sym := g.table.get_type_symbol(node.typ)
|
sym := g.table.get_type_symbol(node.typ)
|
||||||
info := sym.info as table.Struct
|
info := sym.info as table.Struct
|
||||||
for field in info.fields {
|
for field in info.fields {
|
||||||
if field.name in node.fields {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
field_name := c_name(field.name)
|
field_name := c_name(field.name)
|
||||||
g.writeln('\t.$field_name = ${node.var_name}.$field_name,')
|
if field.name in inited_fields {
|
||||||
|
g.write('\t.$field_name = ')
|
||||||
|
g.expr(node.exprs[inited_fields[field.name]])
|
||||||
|
g.writeln(', ')
|
||||||
|
} else {
|
||||||
|
g.writeln('\t.$field_name = ${node.var_name}.$field_name,')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g.write('}')
|
g.write('}')
|
||||||
if g.is_amp {
|
if g.is_amp {
|
||||||
|
@ -3422,19 +3483,19 @@ fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
|
||||||
|
|
||||||
fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp, str_fn_name string) {
|
fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp, str_fn_name string) {
|
||||||
mut convertor := ''
|
mut convertor := ''
|
||||||
mut typename := ''
|
mut typename_ := ''
|
||||||
if sym.parent_idx in table.integer_type_idxs {
|
if sym.parent_idx in table.integer_type_idxs {
|
||||||
convertor = 'int'
|
convertor = 'int'
|
||||||
typename = 'int'
|
typename_ = 'int'
|
||||||
} else if sym.parent_idx == table.f32_type_idx {
|
} else if sym.parent_idx == table.f32_type_idx {
|
||||||
convertor = 'float'
|
convertor = 'float'
|
||||||
typename = 'f32'
|
typename_ = 'f32'
|
||||||
} else if sym.parent_idx == table.f64_type_idx {
|
} else if sym.parent_idx == table.f64_type_idx {
|
||||||
convertor = 'double'
|
convertor = 'double'
|
||||||
typename = 'f64'
|
typename_ = 'f64'
|
||||||
} else if sym.parent_idx == table.bool_type_idx {
|
} else if sym.parent_idx == table.bool_type_idx {
|
||||||
convertor = 'bool'
|
convertor = 'bool'
|
||||||
typename = 'bool'
|
typename_ = 'bool'
|
||||||
} else {
|
} else {
|
||||||
verror("could not generate string method for type \'${styp}\'")
|
verror("could not generate string method for type \'${styp}\'")
|
||||||
}
|
}
|
||||||
|
@ -3443,7 +3504,7 @@ fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp, str_fn_name string) {
|
||||||
if convertor == 'bool' {
|
if convertor == 'bool' {
|
||||||
g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos_lit("${styp}("), (${convertor})it ? tos_lit("true") : tos_lit("false"));')
|
g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos_lit("${styp}("), (${convertor})it ? tos_lit("true") : tos_lit("false"));')
|
||||||
} else {
|
} else {
|
||||||
g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos_lit("${styp}("), tos3(${typename}_str((${convertor})it).str));')
|
g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos_lit("${styp}("), tos3(${typename_}_str((${convertor})it).str));')
|
||||||
}
|
}
|
||||||
g.auto_str_funcs.writeln('\tstring tmp2 = string_add(tmp1, tos_lit(")"));')
|
g.auto_str_funcs.writeln('\tstring tmp2 = string_add(tmp1, tos_lit(")"));')
|
||||||
g.auto_str_funcs.writeln('\tstring_free(&tmp1);')
|
g.auto_str_funcs.writeln('\tstring_free(&tmp1);')
|
||||||
|
@ -3740,7 +3801,9 @@ fn (g &Gen) interface_table() string {
|
||||||
mut methods_struct_def := strings.new_builder(100)
|
mut methods_struct_def := strings.new_builder(100)
|
||||||
methods_struct_def.writeln('$methods_struct_name {')
|
methods_struct_def.writeln('$methods_struct_name {')
|
||||||
mut imethods := map[string]string{} // a map from speak -> _Speaker_speak_fn
|
mut imethods := map[string]string{} // a map from speak -> _Speaker_speak_fn
|
||||||
for method in ityp.methods {
|
mut methodidx := map[string]int
|
||||||
|
for k, method in ityp.methods {
|
||||||
|
methodidx[method.name] = k
|
||||||
typ_name := '_${interface_name}_${method.name}_fn'
|
typ_name := '_${interface_name}_${method.name}_fn'
|
||||||
ret_styp := g.typ(method.return_type)
|
ret_styp := g.typ(method.return_type)
|
||||||
methods_typ_def.write('typedef $ret_styp (*$typ_name)(void* _')
|
methods_typ_def.write('typedef $ret_styp (*$typ_name)(void* _')
|
||||||
|
@ -3786,7 +3849,14 @@ _Interface* I_${cctype}_to_Interface_${interface_name}_ptr(${cctype}* x) {
|
||||||
}')
|
}')
|
||||||
methods_struct.writeln('\t{')
|
methods_struct.writeln('\t{')
|
||||||
st_sym := g.table.get_type_symbol(st)
|
st_sym := g.table.get_type_symbol(st)
|
||||||
for method in st_sym.methods {
|
mut method := table.Fn{}
|
||||||
|
for _, m in ityp.methods {
|
||||||
|
for mm in st_sym.methods {
|
||||||
|
if mm.name == m.name {
|
||||||
|
method = mm
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
if method.name !in imethods {
|
if method.name !in imethods {
|
||||||
// a method that is not part of the interface should be just skipped
|
// a method that is not part of the interface should be just skipped
|
||||||
continue
|
continue
|
||||||
|
@ -3872,8 +3942,8 @@ fn (mut g Gen) array_init(it ast.ArrayInit) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
len := it.exprs.len
|
len := it.exprs.len
|
||||||
g.write('new_array_from_c_array($len, $len, sizeof($elem_type_str), ')
|
g.write('new_array_from_c_array($len, $len, sizeof($elem_type_str), _MOV(($elem_type_str[$len]){')
|
||||||
g.write('($elem_type_str[$len]){\n\t\t')
|
g.writeln('')
|
||||||
for i, expr in it.exprs {
|
for i, expr in it.exprs {
|
||||||
if it.is_interface {
|
if it.is_interface {
|
||||||
// sym := g.table.get_type_symbol(it.interface_types[i])
|
// sym := g.table.get_type_symbol(it.interface_types[i])
|
||||||
|
@ -3886,7 +3956,8 @@ fn (mut g Gen) array_init(it ast.ArrayInit) {
|
||||||
}
|
}
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
g.write('\n})')
|
g.writeln('')
|
||||||
|
g.write('}))')
|
||||||
}
|
}
|
||||||
|
|
||||||
// `ui.foo(button)` =>
|
// `ui.foo(button)` =>
|
||||||
|
|
|
@ -391,9 +391,9 @@ typedef byte array_fixed_byte_300 [300];
|
||||||
typedef byte array_fixed_byte_400 [400];
|
typedef byte array_fixed_byte_400 [400];
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
#ifndef bool
|
#ifndef bool
|
||||||
typedef int bool;
|
typedef int bool;
|
||||||
#define true 1
|
#define true 1
|
||||||
#define false 0
|
#define false 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -618,7 +618,7 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !g.is_json_fn {
|
if !g.is_json_fn {
|
||||||
g.write('&/*qq*/')
|
g.write('(voidptr)&/*qq*/')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.expr_with_cast(arg.expr, arg.typ, expected_type)
|
g.expr_with_cast(arg.expr, arg.typ, expected_type)
|
||||||
|
|
|
@ -23,7 +23,7 @@ void _STR_PRINT_ARG(const char *fmt, char** refbufp, int *nbytes, int *memsize,
|
||||||
}
|
}
|
||||||
// increase buffer (somewhat exponentially)
|
// increase buffer (somewhat exponentially)
|
||||||
*memsize += (*memsize + *memsize) / 3 + guess;
|
*memsize += (*memsize + *memsize) / 3 + guess;
|
||||||
*refbufp = realloc(*refbufp, *memsize);
|
*refbufp = (char*)realloc((void*)*refbufp, *memsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ string _STR(const char *fmt, int nfmts, ...) {
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
int memsize = 128;
|
int memsize = 128;
|
||||||
int nbytes = 0;
|
int nbytes = 0;
|
||||||
char* buf = malloc(memsize);
|
char* buf = (char*)malloc(memsize);
|
||||||
va_start(argptr, nfmts);
|
va_start(argptr, nfmts);
|
||||||
for (int i=0; i<nfmts; i++) {
|
for (int i=0; i<nfmts; i++) {
|
||||||
int k = strlen(fmt);
|
int k = strlen(fmt);
|
||||||
|
@ -80,12 +80,12 @@ string _STR(const char *fmt, int nfmts, ...) {
|
||||||
}
|
}
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
buf[nbytes] = 0;
|
buf[nbytes] = 0;
|
||||||
buf = realloc(buf, nbytes+1);
|
buf = (char*)realloc((void*)buf, nbytes+1);
|
||||||
#ifdef DEBUG_ALLOC
|
#ifdef DEBUG_ALLOC
|
||||||
//puts('_STR:');
|
//puts('_STR:');
|
||||||
puts(buf);
|
puts(buf);
|
||||||
#endif
|
#endif
|
||||||
return tos2(buf);
|
return tos2((byteptr)buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
string _STR_TMP(const char *fmt, ...) {
|
string _STR_TMP(const char *fmt, ...) {
|
||||||
|
|
|
@ -1402,6 +1402,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
||||||
}
|
}
|
||||||
// type MyType int
|
// type MyType int
|
||||||
parent_type := first_type
|
parent_type := first_type
|
||||||
|
parent_name := p.table.get_type_symbol(parent_type).name
|
||||||
pid := parent_type.idx()
|
pid := parent_type.idx()
|
||||||
p.table.register_type_symbol(table.TypeSymbol{
|
p.table.register_type_symbol(table.TypeSymbol{
|
||||||
kind: .alias
|
kind: .alias
|
||||||
|
@ -1410,6 +1411,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
||||||
mod: p.mod
|
mod: p.mod
|
||||||
info: table.Alias{
|
info: table.Alias{
|
||||||
foo: ''
|
foo: ''
|
||||||
|
is_c: parent_name.len > 2 && parent_name[0] == `C` && parent_name[1] == `.`
|
||||||
}
|
}
|
||||||
is_public: is_pub
|
is_public: is_pub
|
||||||
})
|
})
|
||||||
|
|
|
@ -575,6 +575,7 @@ pub:
|
||||||
pub struct Alias {
|
pub struct Alias {
|
||||||
pub:
|
pub:
|
||||||
foo string
|
foo string
|
||||||
|
is_c bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: FExpr here is a actually an ast.Expr .
|
// NB: FExpr here is a actually an ast.Expr .
|
||||||
|
|
|
@ -5,9 +5,9 @@ module token
|
||||||
|
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
pub:
|
pub:
|
||||||
|
len int // length of the literal in the source
|
||||||
line_nr int // the line number in the source where the token occured
|
line_nr int // the line number in the source where the token occured
|
||||||
pos int // the position of the token in scanner text
|
pos int // the position of the token in scanner text
|
||||||
len int // length of the literal in the source
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (pos Position) str() string {
|
pub fn (pos Position) str() string {
|
||||||
|
@ -24,8 +24,8 @@ pub fn (pos Position) extend(end Position) Position {
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (tok &Token) position() Position {
|
pub fn (tok &Token) position() Position {
|
||||||
return Position{
|
return Position{
|
||||||
|
len: tok.len
|
||||||
line_nr: tok.line_nr - 1
|
line_nr: tok.line_nr - 1
|
||||||
pos: tok.pos
|
pos: tok.pos
|
||||||
len: tok.len
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue