initial Nim compiler and standard library support

https://nim-lang.org/

Fix #1879
This commit is contained in:
Emery Hemingway 2017-04-01 12:49:30 -05:00 committed by Christian Helmuth
parent d0bc389e93
commit 5f27c7b9eb
14 changed files with 354 additions and 0 deletions

View File

@ -85,6 +85,41 @@ endif
$(MSG_CONVERT)$@ $(MSG_CONVERT)$@
$(VERBOSE)ar p $< $*.0.o > $@ $(VERBOSE)ar p $< $*.0.o > $@
#
# Compiling Nim source code
#
ifneq ($(SRC_NIM),)
ifeq ($(NIM_CPU),)
$(warning NIM_CPU not defined for any of the following SPECS: $(SPECS))
else
NIM_MAKEFILES := $(foreach X,$(SRC_NIM),$(X).mk)
NIM_ARGS = --compileOnly --os:genode --cpu:$(NIM_CPU)
NIM_ARGS += --verbosity:0 --hint[Processing]:off --nimcache:.
NIM_ARGS += $(NIM_OPT)
# Generate the C++ sources and compilation info
#
# Unfortunately the existing sources must be purged
# because of comma problems in the JSON recipe
%.nim.mk: %.nim
$(MSG_BUILD)$(basename $@).cpp
$(VERBOSE) rm -f stdlib_*.cpp
$(VERBOSE)$(NIM) compileToCpp $(NIM_ARGS) $<
$(VERBOSE)$(JQ) --raw-output '"SRC_O_NIM +=" + (.link | join(" ")) +"\n" + (.compile | map((.[0] | sub("cpp$$";"o: ")) + .[0] + "\n\t"+(.[1] | sub("^g\\++";"$$(MSG_COMP)$$@\n\t$$(VERBOSE)$$(NIM_CC)"))) | join("\n"))' < $(basename $(basename $@)).json > $@
NIM_CC := $(CXX) $(CXX_DEF) $(CC_CXX_OPT) $(INCLUDES) -D__GENODE__
# Parse the generated makefiles
-include $(NIM_MAKEFILES)
# Append the new objects
SRC_O += $(sort $(SRC_O_NIM))
endif
endif
# #
# Assembler files that must be preprocessed are fed to the C compiler. # Assembler files that must be preprocessed are fed to the C compiler.
# #

View File

@ -50,6 +50,16 @@ STRIP = $(CUSTOM_STRIP)
GNATMAKE = $(CUSTOM_GNATMAKE) GNATMAKE = $(CUSTOM_GNATMAKE)
HOST_CC = $(CUSTOM_HOST_CC) HOST_CC = $(CUSTOM_HOST_CC)
#
# Nim toolchain
#
NIM ?= nim
#
# JSON parsing utility
#
JQ ?= jq
# #
# Compiler and Linker options # Compiler and Linker options
# #

View File

@ -5,6 +5,8 @@ REP_INC_DIR += include/spec/arm
SPECS += 32bit SPECS += 32bit
NIM_CPU ?= arm
# #
# Prevent compiler message # Prevent compiler message
# "note: the mangling of 'va_list' has changed in GCC 4.4" # "note: the mangling of 'va_list' has changed in GCC 4.4"

View File

@ -16,5 +16,7 @@ CC_MARCH ?= -march=i686 -m32
LD_MARCH ?= -melf_i386 LD_MARCH ?= -melf_i386
AS_MARCH ?= -march=i686 --32 AS_MARCH ?= -march=i686 --32
NIM_CPU ?= i386
include $(BASE_DIR)/mk/spec/32bit.mk include $(BASE_DIR)/mk/spec/32bit.mk
include $(BASE_DIR)/mk/spec/x86.mk include $(BASE_DIR)/mk/spec/x86.mk

View File

@ -20,5 +20,7 @@ CC_MARCH ?= -m64
# #
LD_MARCH ?= -melf_x86_64 LD_MARCH ?= -melf_x86_64
NIM_CPU ?= amd64
include $(BASE_DIR)/mk/spec/64bit.mk include $(BASE_DIR)/mk/spec/64bit.mk
include $(BASE_DIR)/mk/spec/x86.mk include $(BASE_DIR)/mk/spec/x86.mk

View File

@ -55,3 +55,8 @@ CC_OPT += -D__ISO_C_VISIBLE=1999
# or 'sincosf', which is a GNU extension, not provided by our libc. # or 'sincosf', which is a GNU extension, not provided by our libc.
# #
CC_OPT += -fno-builtin-sin -fno-builtin-cos -fno-builtin-sinf -fno-builtin-cosf CC_OPT += -fno-builtin-sin -fno-builtin-cos -fno-builtin-sinf -fno-builtin-cosf
#
# Enable Nim POSIX support when linking with this library
#
NIM_OPT += -d:posix

View File

@ -0,0 +1 @@
NIM_OPT += --threads:on --tlsEmulation:on

View File

View File

@ -0,0 +1,62 @@
set build_components {
core init
drivers/timer
drivers/rtc
test/nim
}
build $build_components
create_boot_directory
set config {
<config>
<parent-provides>
<service name="CPU"/>
<service name="LOG"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RAM"/>
<service name="RM"/>
<service name="ROM"/>
<service name="SIGNAL"/>
</parent-provides>
<default caps="64"/>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Timer"/> </provides>
</start>
<start name="rtc_drv">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Rtc"/> </provides>
</start>
<start name="test-nim">
<resource name="RAM" quantum="10M"/>
<config>
<vfs>
<ram/> <log/> <rtc/>
</vfs>
<libc stdout="/log" stderr="/log" rtc="/rtc"/>
</config>
</start>
</config>
}
install_config $config
set boot_modules {
core init ld.lib.so
libc.lib.so
rtc_drv
test-nim
timer
}
build_boot_image $boot_modules
append qemu_args "-nographic"
run_genode_until {child "test-nim" exited with exit value 0} 30

View File

@ -0,0 +1,84 @@
assert_spec linux
set build_components {
core init
drivers/timer drivers/nic server/ram_fs server/vfs
test/nim_echo_server
lib/vfs/lxip
}
source ${genode_dir}/repos/base/run/platform_drv.inc
append_platform_drv_build_components
build $build_components
create_boot_directory
set config {
<config verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="RAM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="CAP"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="SIGNAL"/>
</parent-provides>
<default caps="128"/>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Timer"/> </provides>
</start>
<start name="nic_drv">
<binary name="linux_nic_drv"/>
<resource name="RAM" quantum="2M"/>
<provides> <service name="Nic"/> </provides>
</start>
<start name="netty">
<binary name="test-nim_echo_server"/>
<resource name="RAM" quantum="32M"/>
<config ld_verbose="yes">
<vfs>
<dir name="socket">
<lxip ip_addr="10.0.2.55" netmask="255.255.255.0" gateway="10.0.2.1" nameserver="8.8.8.8"/>
</dir>
<dir name="dev"> <log/> </dir>
<dir name="tmp"> <ram/> </dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
</config>
</start>
}
append_platform_drv_config
append config {
</config>
}
install_config $config
set boot_modules {
core init timer linux_nic_drv ram_fs vfs
ld.lib.so libc.lib.so libm.lib.so
libc_resolv.lib.so stdcxx.lib.so libc_pipe.lib.so
vfs_lxip.lib.so lxip.lib.so
test-nim_echo_server
}
append_platform_drv_boot_modules
build_boot_image $boot_modules
run_genode_until forever
# vi: set ft=tcl :

View File

@ -0,0 +1,112 @@
import unittest
const
Text = "Hello world!"
suite "echo":
echo Text
suite "system":
echo "compile date: ", CompileDate, " - ", CompileTime
echo("endianness: ",
case cpuEndian:
of littleEndian:
"littleEndian"
of bigEndian:
"bigEndian"
)
echo "hostCPU: ", hostCPU
echo "NimVersion: ", NimVersion
echo "nativeStackTraceSupported: ", $nativeStackTraceSupported
echo "getStackTrace:\n", getStackTrace()
echo "getFreeMem: ", getFreeMem()
echo "getTotalMem: ", getTotalMem()
echo "getOccupiedMem: ", getOccupiedMem()
test "isMainModule":
assert isMainModule == true
test "hostOS == genode":
assert hostOS == "genode"
test "alloc/dealloc":
let p = alloc 768
assert(not p.isNil)
dealloc p
test "exception handling":
type NovelError = object of SystemError
try: raise newException(NovelError, "test exception")
except NovelError:
discard
import locks, threadpool
suite "threadpool":
test "spawn":
var L: Lock
proc threadProc(interval: tuple[a,b: int]) =
for i in interval.a..interval.b:
acquire L
echo i
release L
initLock L
for i in 0..3:
spawn threadProc((i*10, i*10+4))
sync()
deinitLock L
test "threadvar":
var
L: Lock
x {.threadvar.}: int
y: int
proc printVal(id: string) =
acquire L
echo(
id,
" x: ", repr(addr(x)),
" y: ", repr(addr(y))
)
inc x
inc y
release L
initLock L
release L
printVal("main thread")
for i in 1..4:
spawn printVal("spawn "& $i)
sync()
deinitLock L
suite "I/O":
const
TestFile = "/testfile"
Text = NimVersion & " - " & CompileDate & " - " & CompileTime
test "writeFile":
writeFile(TestFile, Text)
test "readFile":
assert readFile(TestFile) == Text
suite "staticExec":
const rev = staticExec("git describe")
echo "compile time 'git describe': ", rev
import times
suite "time":
echo "epochTime() float value: ", epochTime()
echo "getTime() float value: ", toSeconds(getTime())
echo "cpuTime() float value: ", cpuTime()
echo "An hour from now : ", getLocalTime(getTime()) + 1.hours
echo "An hour from (UTC) now: ", getGmTime(getTime()) + initInterval(0,0,0,1)
test "getTime":
assert(getTime() != 0.Time)
suite "garbage collector":
echo GC_getStatistics()
echo "done"

View File

@ -0,0 +1,6 @@
TARGET = test-nim
LIBS = nim-threads libc
SRC_NIM = main.nim
# Enable extra system assertions
NIM_OPT += -d:useSysAssert

View File

@ -0,0 +1,27 @@
import asyncnet, asyncdispatch
const
CRLF* = "\c\L"
proc processClient(address: string, client: AsyncSocket) {.async.} =
echo "accepted connection from ", address
while not client.isClosed():
let line = await client.recvLine()
if line == "":
break
await client.send(line & CRLF)
echo address, " closed connection"
proc serve() {.async.} =
let server = newAsyncSocket()
server.bindAddr(7.Port)
server.listen()
echo "echo service listening on port 7"
while true:
let res = await server.acceptAddr()
asyncCheck processClient(res[0], res[1])
asyncCheck serve()
runForever()

View File

@ -0,0 +1,6 @@
TARGET = test-nim_echo_server
LIBS = libc libc_resolv
SRC_NIM = main.nim
# Enable extra system assertions
NIM_OPT += -d:useSysAssert