├── .gitignore ├── .travis.yml ├── AUTHORS.md ├── BOOTSTRAP ├── CHANGELOG.md ├── CONTRIBUTE ├── FAQ.rst ├── INSTALL ├── INSTALL.win32 ├── LICENSE ├── Makefile ├── README.md ├── docs ├── HOWTO ├── art │ └── logo.txt ├── generics │ └── Functions.md ├── internals │ ├── FuncType.md │ ├── Metaclasses.md │ ├── Resolving.md │ └── Tutorial.md ├── rock.1 ├── rock.1.txt └── workflow │ └── ReleaseToGit.md ├── extensions ├── Makefile ├── README.md └── fancy-backtrace │ ├── .gitignore │ ├── Makefile │ ├── Makefile.linux │ ├── Makefile.osx │ ├── Makefile.unsupported │ ├── Makefile.win32 │ ├── README.md │ └── fancy_backtrace.c ├── pcre.use ├── rock.use ├── sdk-dynlib.use ├── sdk-net.use ├── sdk.use ├── sdk ├── io │ ├── BinarySequence.ooc │ ├── BufferReader.ooc │ ├── BufferWriter.ooc │ ├── File.ooc │ ├── FileReader.ooc │ ├── FileWriter.ooc │ ├── Reader.ooc │ ├── StringReader.ooc │ ├── Writer.ooc │ └── native │ │ ├── FileUnix.ooc │ │ └── FileWin32.ooc ├── lang │ ├── Abstractions.ooc │ ├── Array.h │ ├── Backtrace.ooc │ ├── Buffer.ooc │ ├── BufferIterator.ooc │ ├── Character.ooc │ ├── Exception.ooc │ ├── Format.ooc │ ├── IO.ooc │ ├── Iterators.ooc │ ├── Memory.ooc │ ├── Numbers.ooc │ ├── String.ooc │ ├── VarArgs.ooc │ ├── internals │ │ └── mangling.ooc │ ├── stdlib.ooc │ └── types.ooc ├── math.ooc ├── math.use ├── math │ └── Random.ooc ├── native │ └── win32 │ │ ├── errors.ooc │ │ └── types.ooc ├── net │ ├── Address.ooc │ ├── DNS.ooc │ ├── Exceptions.ooc │ ├── ServerSocket.ooc │ ├── Socket.ooc │ ├── TCPSocket.ooc │ ├── UDPSocket.ooc │ ├── berkeley.ooc │ ├── translation.ooc │ └── utilities.ooc ├── os │ ├── Coro.ooc │ ├── Dynlib.ooc │ ├── Env.ooc │ ├── FileDescriptor.ooc │ ├── JobPool.ooc │ ├── Pipe.ooc │ ├── Process.ooc │ ├── ShellUtils.ooc │ ├── System.ooc │ ├── Terminal.ooc │ ├── Time.ooc │ ├── mmap.ooc │ ├── native │ │ ├── CoroUnix.ooc │ │ ├── CoroWin32.ooc │ │ ├── PipeUnix.ooc │ │ ├── PipeWin32.ooc │ │ ├── ProcessUnix.ooc │ │ ├── ProcessWin32.ooc │ │ ├── TerminalUnix.ooc │ │ └── TerminalWin32.ooc │ ├── unistd.ooc │ └── wait.ooc ├── siphash.use ├── structs │ ├── ArrayList.ooc │ ├── Bag.ooc │ ├── HashBag.ooc │ ├── HashMap.ooc │ ├── LinkedList.ooc │ ├── List.ooc │ ├── MultiMap.ooc │ ├── Stack.ooc │ └── Stick.ooc ├── text │ ├── Base64.ooc │ ├── EscapeSequence.ooc │ ├── Opts.ooc │ ├── Regexp.ooc │ ├── Shlex.ooc │ ├── StringTemplate.ooc │ ├── StringTokenizer.ooc │ ├── json.ooc │ └── json │ │ ├── DSL.ooc │ │ ├── Generator.ooc │ │ └── Parser.ooc └── threading │ ├── Thread.ooc │ └── native │ ├── MutexUnix.ooc │ ├── MutexWin32.ooc │ ├── ThreadLocalUnix.ooc │ ├── ThreadLocalWin32.ooc │ ├── ThreadUnix.ooc │ └── ThreadWin32.ooc ├── source └── rock │ ├── RockVersion.ooc │ ├── backend │ ├── cnaughty │ │ ├── AccessWriter.ooc │ │ ├── AwesomeWriter.ooc │ │ ├── CGenerator.ooc │ │ ├── CastWriter.ooc │ │ ├── ClassDeclWriter.ooc │ │ ├── ControlStatementWriter.ooc │ │ ├── CoverDeclWriter.ooc │ │ ├── EnumDeclWriter.ooc │ │ ├── FunctionCallWriter.ooc │ │ ├── FunctionDeclWriter.ooc │ │ ├── InterfaceDeclWriter.ooc │ │ ├── ModuleWriter.ooc │ │ ├── Skeleton.ooc │ │ ├── TypeWriter.ooc │ │ ├── VariableAccessChecker.ooc │ │ └── VersionWriter.ooc │ ├── json │ │ └── JSONGenerator.ooc │ └── lua │ │ └── LuaGenerator.ooc │ ├── frontend │ ├── AstBuilder.ooc │ ├── BuildParams.ooc │ ├── CommandLine.ooc │ ├── Help.ooc │ ├── NagaQueen.c │ ├── PathList.ooc │ ├── Target.ooc │ ├── Token.ooc │ ├── drivers │ │ ├── AndroidDriver.ooc │ │ ├── Archive.ooc │ │ ├── CCompiler.ooc │ │ ├── CMakeDriver.ooc │ │ ├── DependencyGraph.ooc │ │ ├── Driver.ooc │ │ ├── DummyDriver.ooc │ │ ├── Flags.ooc │ │ ├── MakeDriver.ooc │ │ ├── MetaDriver.ooc │ │ ├── SequenceDriver.ooc │ │ └── SourceFolder.ooc │ └── pkgconfig │ │ ├── PkgConfigFrontend.ooc │ │ └── PkgInfo.ooc │ ├── io │ ├── CachedFileWriter.ooc │ └── TabbedWriter.ooc │ ├── middle │ ├── Addon.ooc │ ├── AddressOf.ooc │ ├── Argument.ooc │ ├── ArrayAccess.ooc │ ├── ArrayCreation.ooc │ ├── ArrayLiteral.ooc │ ├── BaseType.ooc │ ├── BinaryOp.ooc │ ├── Block.ooc │ ├── BoolLiteral.ooc │ ├── CallChain.ooc │ ├── Cast.ooc │ ├── CharLiteral.ooc │ ├── ClassDecl.ooc │ ├── CommaSequence.ooc │ ├── Comparison.ooc │ ├── Conditional.ooc │ ├── ControlStatement.ooc │ ├── CoverDecl.ooc │ ├── Declaration.ooc │ ├── Dereference.ooc │ ├── Else.ooc │ ├── EnumDecl.ooc │ ├── Expression.ooc │ ├── FloatLiteral.ooc │ ├── FlowControl.ooc │ ├── Foreach.ooc │ ├── FuncType.ooc │ ├── FunctionCall.ooc │ ├── FunctionDecl.ooc │ ├── If.ooc │ ├── Import.ooc │ ├── Include.ooc │ ├── IntLiteral.ooc │ ├── InterfaceDecl.ooc │ ├── InterfaceImpl.ooc │ ├── Line.ooc │ ├── Literal.ooc │ ├── Match.ooc │ ├── Module.ooc │ ├── NamespaceDecl.ooc │ ├── Node.ooc │ ├── NullLiteral.ooc │ ├── OperatorDecl.ooc │ ├── Parenthesis.ooc │ ├── PropertyDecl.ooc │ ├── RangeLiteral.ooc │ ├── Return.ooc │ ├── SafeNavigation.ooc │ ├── Scope.ooc │ ├── Statement.ooc │ ├── StringLiteral.ooc │ ├── StructLiteral.ooc │ ├── TemplateDef.ooc │ ├── Ternary.ooc │ ├── Try.ooc │ ├── Tuple.ooc │ ├── Type.ooc │ ├── TypeDecl.ooc │ ├── TypeList.ooc │ ├── UnaryOp.ooc │ ├── Use.ooc │ ├── UseDef.ooc │ ├── VariableAccess.ooc │ ├── VariableDecl.ooc │ ├── Version.ooc │ ├── Visitor.ooc │ ├── While.ooc │ ├── algo │ │ ├── ImportClassifier.ooc │ │ ├── autoReturn.ooc │ │ └── typeAnalysis.ooc │ └── tinker │ │ ├── Errors.ooc │ │ ├── Resolver.ooc │ │ ├── Response.ooc │ │ ├── Tinkerer.ooc │ │ └── Trail.ooc │ ├── rock.ooc │ └── utils │ └── FileUtils.ooc ├── test ├── .gitignore ├── README.md ├── compiler │ ├── addons │ │ ├── generic-addon-realized.ooc │ │ ├── generic-addon-return.ooc │ │ ├── generic-addon-simple.ooc │ │ ├── generic-addon-template-realized.ooc │ │ └── generic-mixed-addon.ooc │ ├── arrays │ │ ├── array-as-arg.ooc │ │ ├── array-as-arg2.ooc │ │ ├── array-to-arraylist.ooc │ │ ├── array-vdfe.ooc │ │ ├── cast-to-array.ooc │ │ ├── cast-to-array2.ooc │ │ ├── return-array.ooc │ │ └── return-array2.ooc │ ├── classes │ │ ├── class-template-extend-from-non-template.ooc │ │ ├── class-template-partial-extend.ooc │ │ ├── class-template-simple.ooc │ │ ├── eventually-final.ooc │ │ ├── final-no-longer-1.ooc │ │ ├── final-no-longer-2.ooc │ │ ├── generic-template-scoring.ooc │ │ ├── load-function-once.ooc │ │ ├── parent-constructor.ooc │ │ └── reverse-constructor-args-on-extend.ooc │ ├── closures │ │ ├── acs-reference-capture.ooc │ │ ├── nest-up-and-away.ooc │ │ ├── nested-assignment.ooc │ │ ├── nested-closures.ooc │ │ └── non-acs-in-closure.ooc │ ├── control │ │ ├── foreach-index.ooc │ │ ├── foreach-range-generated.ooc │ │ ├── foreach-range-index.ooc │ │ ├── foreach-range.ooc │ │ ├── foreach.ooc │ │ ├── gencall-inbetween.ooc │ │ └── invalid-match-type-inference.ooc │ ├── covers │ │ ├── cover-from-underlying-access.ooc │ │ ├── cover-template-cross-reference.ooc │ │ ├── cover-template-unused-segfault.ooc │ │ ├── cover-template-vector.ooc │ │ ├── cover-templates-generic-function.ooc │ │ ├── cover-templates-generic-function2.ooc │ │ ├── cover-templates-generic-function3.ooc │ │ ├── cover-templates-string-interpolation.ooc │ │ ├── cover-templates-string-interpolation2.ooc │ │ ├── cover-templates.ooc │ │ ├── cover-templates2.ooc │ │ ├── not-object-in-match.ooc │ │ ├── pointer-comparison.ooc │ │ ├── template-invalid-assignment.ooc │ │ └── template-valid-assignment.ooc │ ├── enums │ │ └── versioned-enum.ooc │ ├── functions │ │ ├── call-combo1.ooc │ │ ├── call-combo2.ooc │ │ ├── generic-return.ooc │ │ ├── generic-return2.ooc │ │ ├── inference-precision-loss.ooc │ │ ├── invalid-abstract-func-addon.ooc │ │ ├── invalid-abstract-outside-class.ooc │ │ ├── invalid-return1.ooc │ │ ├── invalid-return2.ooc │ │ ├── invalid-return3.ooc │ │ ├── malformed-function.ooc │ │ ├── multi-init.ooc │ │ ├── redefinition-in-extend-suffix.ooc │ │ ├── redefinition-in-extend-vs-base.ooc │ │ ├── redefinition-in-extend.ooc │ │ ├── segfault-on-build.ooc │ │ ├── static-func-addon.ooc │ │ ├── unqualified-static-first-class-call.ooc │ │ ├── valid-return.ooc │ │ ├── var-redef1.ooc │ │ ├── var-redef2.ooc │ │ └── var-redef3.ooc │ ├── generics │ │ ├── cannot-reassign-typeargs.ooc │ │ ├── casting-to-generic.ooc │ │ ├── function-typearg-infer-from-closure-return-type.ooc │ │ ├── function-typearg-infer-from-nested-generic-argument.ooc │ │ ├── generic-member.ooc │ │ ├── generic-member2.ooc │ │ ├── generic-member3.ooc │ │ ├── infer-from-type-hierarchy.ooc │ │ ├── iterate-hashmap-keys.ooc │ │ ├── match-generic-types.ooc │ │ ├── pass-invalid-generic-arg.ooc │ │ ├── pointer-size.ooc │ │ ├── reconcile-1.ooc │ │ ├── reconcile-not-1.ooc │ │ ├── typewidth.ooc │ │ ├── unwrap-with-return-args.ooc │ │ ├── use-owner-not-this.ooc │ │ └── use-owner-not-this2.ooc │ ├── interfaces │ │ ├── interface-provided-function.ooc │ │ ├── invalid-function-implementation.ooc │ │ ├── multiple-interface-implementation.ooc │ │ └── simple-function-implementation.ooc │ ├── literals │ │ ├── array-literal-in-class.ooc │ │ ├── fp-literal-scientific.ooc │ │ ├── fp-literal-suffixes.ooc │ │ ├── int-literal-suffixes.ooc │ │ ├── interpolated-string-literal.ooc │ │ ├── range-literal.ooc │ │ ├── string-literal-escapes.ooc │ │ ├── string-literal-octal.ooc │ │ └── string-literal-raw.ooc │ ├── namespaces │ │ ├── namespaced-import-function.ooc │ │ └── namespaced-import-type.ooc │ ├── operators │ │ ├── abstract-overload-member.ooc │ │ ├── all-equal-overloads.ooc │ │ ├── array-overload-member.ooc │ │ ├── array-overload.ooc │ │ ├── assign-numeric-and-cover.ooc │ │ ├── assign-numeric-and-reference.ooc │ │ ├── binaryop-array-access-side-effects.ooc │ │ ├── check-on-definition.ooc │ │ ├── comparison-overload-member.ooc │ │ ├── comparison-overload.ooc │ │ ├── invalid-abstract-overload.ooc │ │ ├── null-coalescing-associativity.ooc │ │ ├── null-coalescing-single-evaluation.ooc │ │ ├── null-coalescing.ooc │ │ ├── overload-order.ooc │ │ ├── safe-navigation-simple.ooc │ │ ├── safe-navigation-with-nullco.ooc │ │ ├── unary-minus-non-numeric.ooc │ │ ├── unary-minus.ooc │ │ ├── unary-overload-member.ooc │ │ ├── unary-overload.ooc │ │ ├── unary-plus-non-numeric.ooc │ │ └── unary-plus.ooc │ ├── pointers │ │ ├── references-accessing.ooc │ │ └── references-assigning.ooc │ ├── properties │ │ ├── call-properties.ooc │ │ ├── extend-pdfe.ooc │ │ ├── extend-properties.ooc │ │ ├── no-generic-initialization-for-properties.ooc │ │ ├── operator_assign_setter.ooc │ │ ├── pdfe-cover.ooc │ │ └── pdfe.ooc │ ├── syntax │ │ ├── misplaced-oocdocs1.ooc │ │ ├── misplaced-oocdocs2.ooc │ │ ├── oocdocs-not.ooc │ │ └── version-blocks.ooc │ ├── tuples │ │ ├── complex-swap.ooc │ │ ├── ncall.ooc │ │ ├── tuple-assign.ooc │ │ ├── tuple-assign2.ooc │ │ ├── tuple-multidecl-omit.ooc │ │ ├── tuple-multidecl-precedence.ooc │ │ ├── tuple-multidecl.ooc │ │ └── tuple-swap.ooc │ ├── types │ │ ├── cast-to-struct.ooc │ │ ├── cast-to-struct2.ooc │ │ ├── common-root-object.ooc │ │ └── type-analysis.ooc │ └── variables │ │ ├── builtins.ooc │ │ ├── class-of-any-type.ooc │ │ ├── constnum.h │ │ └── extern-const-reference.ooc └── sdk │ ├── io │ ├── exists.ooc │ ├── fileexec.ooc │ ├── find.ooc │ ├── rm.ooc │ └── rm_rf.ooc │ ├── lang │ ├── .gitignore │ ├── Buffer.ooc │ ├── crash.ooc │ ├── cstr.ooc │ ├── limits.ooc │ └── longformat.ooc │ ├── os │ ├── .gitignore │ ├── coroutines.ooc │ ├── dynlib.ooc │ ├── filedesc.ooc │ ├── pipe1.ooc │ ├── pipe1b.ooc │ ├── pipe2.ooc │ ├── pool.ooc │ ├── process.ooc │ ├── processcwd.ooc │ ├── processenv.ooc │ ├── processinvalid.ooc │ └── shell.ooc │ ├── structs │ ├── double-remove.ooc │ ├── hashmap_resize_test.ooc │ ├── hashmap_test.ooc │ ├── multimap_iterator_test.ooc │ ├── multimap_resize_test.ooc │ ├── multimap_test.ooc │ └── paths.ooc │ ├── text │ ├── .gitignore │ ├── base64.ooc │ ├── json │ │ ├── dsl.ooc │ │ └── null-as-string.ooc │ └── shlex-test.ooc │ └── threading │ ├── mutex.ooc │ ├── recmutex.ooc │ └── threadlocal.ooc ├── utils ├── clean-whitespace.sh ├── download-bootstrap.sh ├── ooc-install.sh ├── pre-commit └── rock-script.sh └── vendor ├── README.md └── gc ├── BCC_MAKEFILE ├── CMakeLists.txt ├── ChangeLog ├── EMX_MAKEFILE ├── MacProjects.sit.hqx ├── Mac_files ├── MacOS_Test_config.h ├── MacOS_config.h ├── dataend.c └── datastart.c ├── Makefile.DLLs ├── Makefile.am ├── Makefile.direct ├── Makefile.dj ├── Makefile.in ├── NT_MAKEFILE ├── NT_STATIC_THREADS_MAKEFILE ├── NT_X64_STATIC_THREADS_MAKEFILE ├── NT_X64_THREADS_MAKEFILE ├── OS2_MAKEFILE ├── PCR-Makefile ├── README.QUICK ├── SMakefile.amiga ├── WCC_MAKEFILE ├── aclocal.m4 ├── allchblk.c ├── alloc.c ├── alpha_mach_dep.S ├── autogen.sh ├── backgraph.c ├── bdw-gc.pc.in ├── blacklst.c ├── build_atomic_ops.sh ├── build_atomic_ops.sh.cygwin ├── callprocs ├── checksums.c ├── compile ├── config.guess ├── config.sub ├── configure ├── configure.ac ├── configure.host ├── cord ├── cord.am ├── cordbscs.c ├── cordprnt.c ├── cordtest.c ├── cordxtra.c ├── de.c ├── de_cmds.h ├── de_win.ICO ├── de_win.RC ├── de_win.c └── de_win.h ├── darwin_stop_world.c ├── dbg_mlc.c ├── depcomp ├── digimars.mak ├── doc ├── README ├── README.DGUX386 ├── README.Mac ├── README.MacOSX ├── README.OS2 ├── README.amiga ├── README.arm.cross ├── README.autoconf ├── README.changes ├── README.cmake ├── README.contributors ├── README.cords ├── README.darwin ├── README.dj ├── README.environment ├── README.ews4800 ├── README.hp ├── README.linux ├── README.macros ├── README.rs6000 ├── README.sgi ├── README.solaris2 ├── README.uts ├── README.win32 ├── README.win64 ├── barrett_diagram ├── debugging.html ├── doc.am ├── gc.man ├── gcdescr.html ├── gcinterface.html ├── leak.html ├── overview.html ├── porting.html ├── scale.html ├── simple_example.html └── tree.html ├── dyn_load.c ├── extra ├── AmigaOS.c ├── MacOS.c ├── add_gc_prefix.c ├── gc.c ├── gcname.c ├── if_mach.c ├── if_not_there.c ├── msvc_dbg.c ├── setjmp_t.c └── threadlibs.c ├── finalize.c ├── gc.mak ├── gc_cpp.cc ├── gc_cpp.cpp ├── gc_dlopen.c ├── gcj_mlc.c ├── headers.c ├── ia64_save_regs_in_stack.s ├── include ├── cord.h ├── ec.h ├── extra │ ├── gc.h │ └── gc_cpp.h ├── gc.h ├── gc_allocator.h ├── gc_amiga_redirects.h ├── gc_backptr.h ├── gc_config_macros.h ├── gc_cpp.h ├── gc_gcj.h ├── gc_inline.h ├── gc_mark.h ├── gc_pthread_redirects.h ├── gc_tiny_fl.h ├── gc_typed.h ├── gc_version.h ├── include.am ├── javaxfc.h ├── leak_detector.h ├── new_gc_alloc.h ├── private │ ├── config.h.in │ ├── cord_pos.h │ ├── darwin_semaphore.h │ ├── darwin_stop_world.h │ ├── dbg_mlc.h │ ├── gc_hdrs.h │ ├── gc_locks.h │ ├── gc_pmark.h │ ├── gc_priv.h │ ├── gcconfig.h │ ├── msvc_dbg.h │ ├── pthread_stop_world.h │ ├── pthread_support.h │ ├── specific.h │ └── thread_local_alloc.h └── weakpointer.h ├── install-sh ├── libatomic_ops ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── Makefile.am ├── Makefile.in ├── NEWS ├── README ├── aclocal.m4 ├── compile ├── config.guess ├── config.sub ├── configure ├── configure.ac ├── depcomp ├── doc │ ├── COPYING │ ├── LICENSING.txt │ ├── Makefile.am │ ├── Makefile.in │ ├── README.txt │ ├── README_malloc.txt │ ├── README_stack.txt │ └── README_win32.txt ├── install-sh ├── missing ├── mkinstalldirs ├── pkgconfig │ ├── atomic_ops-uninstalled.pc.in │ └── atomic_ops.pc.in ├── src │ ├── Makefile.am │ ├── Makefile.in │ ├── Makefile.msft │ ├── atomic_ops.c │ ├── atomic_ops.h │ ├── atomic_ops │ │ ├── Makefile.am │ │ ├── Makefile.in │ │ ├── generalize-small.h │ │ ├── generalize-small.template │ │ ├── generalize.h │ │ └── sysdeps │ │ │ ├── Makefile.am │ │ │ ├── Makefile.in │ │ │ ├── README │ │ │ ├── acquire_release_volatile.h │ │ │ ├── aligned_atomic_load_store.h │ │ │ ├── all_acquire_release_volatile.h │ │ │ ├── all_aligned_atomic_load_store.h │ │ │ ├── all_atomic_load_store.h │ │ │ ├── ao_t_is_int.h │ │ │ ├── armcc │ │ │ └── arm_v6.h │ │ │ ├── atomic_load_store.h │ │ │ ├── char_acquire_release_volatile.h │ │ │ ├── char_atomic_load_store.h │ │ │ ├── emul_cas.h │ │ │ ├── gcc │ │ │ ├── alpha.h │ │ │ ├── arm.h │ │ │ ├── avr32.h │ │ │ ├── cris.h │ │ │ ├── hexagon.h │ │ │ ├── hppa.h │ │ │ ├── ia64.h │ │ │ ├── m68k.h │ │ │ ├── mips.h │ │ │ ├── powerpc.h │ │ │ ├── s390.h │ │ │ ├── sh.h │ │ │ ├── sparc.h │ │ │ ├── x86.h │ │ │ └── x86_64.h │ │ │ ├── generic_pthread.h │ │ │ ├── hpc │ │ │ ├── hppa.h │ │ │ └── ia64.h │ │ │ ├── ibmc │ │ │ └── powerpc.h │ │ │ ├── icc │ │ │ └── ia64.h │ │ │ ├── int_acquire_release_volatile.h │ │ │ ├── int_aligned_atomic_load_store.h │ │ │ ├── int_atomic_load_store.h │ │ │ ├── msftc │ │ │ ├── arm.h │ │ │ ├── common32_defs.h │ │ │ ├── x86.h │ │ │ └── x86_64.h │ │ │ ├── ordered.h │ │ │ ├── ordered_except_wr.h │ │ │ ├── read_ordered.h │ │ │ ├── short_acquire_release_volatile.h │ │ │ ├── short_aligned_atomic_load_store.h │ │ │ ├── short_atomic_load_store.h │ │ │ ├── standard_ao_double_t.h │ │ │ ├── sunc │ │ │ ├── sparc.S │ │ │ ├── sparc.h │ │ │ ├── x86.h │ │ │ └── x86_64.h │ │ │ ├── test_and_set_t_is_ao_t.h │ │ │ └── test_and_set_t_is_char.h │ ├── atomic_ops_malloc.c │ ├── atomic_ops_malloc.h │ ├── atomic_ops_stack.c │ ├── atomic_ops_stack.h │ ├── atomic_ops_sysdeps.S │ └── config.h.in ├── test-driver └── tests │ ├── Makefile.am │ ├── Makefile.in │ ├── list_atomic.c │ ├── list_atomic.template │ ├── run_parallel.inc │ ├── test_atomic.c │ ├── test_atomic.template │ ├── test_atomic_include.h │ ├── test_malloc.c │ └── test_stack.c ├── ltmain.sh ├── m4 ├── gc_set_version.m4 ├── libtool.m4 ├── ltoptions.m4 ├── ltsugar.m4 ├── ltversion.m4 └── lt~obsolete.m4 ├── mach_dep.c ├── malloc.c ├── mallocx.c ├── mark.c ├── mark_rts.c ├── mips_sgi_mach_dep.s ├── mips_ultrix_mach_dep.s ├── misc.c ├── missing ├── mkinstalldirs ├── new_hblk.c ├── obj_map.c ├── os_dep.c ├── pcr_interface.c ├── pthread_start.c ├── pthread_stop_world.c ├── pthread_support.c ├── ptr_chck.c ├── real_malloc.c ├── reclaim.c ├── rs6000_mach_dep.s ├── sparc_mach_dep.S ├── sparc_netbsd_mach_dep.s ├── sparc_sunos4_mach_dep.s ├── specific.c ├── stubborn.c ├── test-driver ├── tests ├── CMakeLists.txt ├── huge_test.c ├── initsecondarythread.c ├── leak_test.c ├── middle.c ├── realloc_test.c ├── smash_test.c ├── staticrootslib.c ├── staticrootstest.c ├── test.c ├── test_cpp.cc ├── tests.am ├── thread_leak_test.c ├── threadkey_test.c └── trace_test.c ├── thread_local_alloc.c ├── typd_mlc.c └── win32_threads.c /.gitignore: -------------------------------------------------------------------------------- 1 | .anjuta* 2 | old-sdk* 3 | rock-*-source 4 | rock-*-bootstrap-only.tar.* 5 | build 6 | *~ 7 | *.swp 8 | bin 9 | bin-win32 10 | bin-linux 11 | *tmp* 12 | .libs* 13 | .sam-cache 14 | callgrind.out.* 15 | /vendor-prefix 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | addons: 4 | apt: 5 | packages: 6 | - curl 7 | - make 8 | - libgc-dev 9 | - zlib1g-dev 10 | 11 | script: 12 | - export PATH=$PATH:$PWD/bin:$PWD/sam 13 | - export OOC_LIBS=$PWD 14 | - export OOC_FLAGS=--quiet 15 | - make -s rescue 16 | - make clean self 17 | - make clean self 18 | - git clone --depth=1 git://github.com/ooc-lang/sam.git 19 | - (cd sam && rock --quiet sam.use) 20 | - sam test rock.use 21 | 22 | notifications: 23 | webhooks: http://rcmp.pw/freenode/ooc-lang 24 | 25 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | ## Contributors (alphabetically) 2 | 3 | * Alexandros Naskos / [@shamanas](https://github.com/shamanas) 4 | * Amos Wenger / [@fasterthanlime](https://github.com/fasterthanlime) (previously @nddrylliog) 5 | * Brian Callahan / [@ibara](https://github.com/ibara) 6 | * David Hesselbom / [@davidhesselbom](https://github.com/davidhesselbom) 7 | * Dwayne Slater / [@ds84182](https://github.com/ds84182) 8 | * Friedrich Weber / [@fredreichbier](https://github.com/fredreichbier) 9 | * Hongjie Zhai / [@zhaihj](https://github.com/zhaihj) 10 | * Joshua Roesslein / [@joshthecoder](https://github.com/joshthecoder) 11 | * Marie Markwell / [@duckinator](https://github.com/duckinator) 12 | * Martin Brandenburg 13 | * Michael Tremel / [@mt2d2](https://github.com/mt2d2) (previously @itrekkie) 14 | * Noel Cower / [@nilium](https://github.com/nilium) 15 | * Peter Lichard / [@eagle2com](https://github.com/eagle2com) 16 | * [@rofl0r](https://github.com/rofl0r) 17 | * Ryan Gonzalez / [@kirbyfan64](https://github.com/kirbyfan64) 18 | * Scott Olson / [@tsion](https://github.com/tsion) 19 | * Tim J. Howard / [@komiga](https://github.com/komiga) 20 | * Yannic Ahrens / [@showstopper](https://github.com/showstopper) 21 | -------------------------------------------------------------------------------- /BOOTSTRAP: -------------------------------------------------------------------------------- 1 | It looks like you don't have a set of C sources rock can bootstrap from. 2 | 3 | Try running `make rescue`, or when everything else fails, get help on IRC 4 | and/or open an issue here: https://github.com/ooc-lang/rock/issues 5 | -------------------------------------------------------------------------------- /CONTRIBUTE: -------------------------------------------------------------------------------- 1 | How to contribute to rock 2 | ------------------------- 3 | 4 | * Fork the project on github 5 | * Send patches / pull request 6 | 7 | We used to be a lot more open about contributions, but things went awry. 8 | Maybe we'll go back to a more open model later. who knows. 9 | 10 | Working with forks 11 | ------------------ 12 | 13 | GitHub has good documentation on that, everything you need is here: 14 | 15 | * http://help.github.com/forking/ 16 | 17 | If you still have questions, ask on IRC (#ooc-lang channel on Freenode) 18 | 19 | What happens with pull requests? 20 | -------------------------------- 21 | 22 | Pull requests are examined as soon as possible by reviewers. If they need 23 | adjustments to meet our quality standards or we feel they could be 24 | significantly improved, we'll let you know by commenting on the pull request. 25 | 26 | When the commits are ready to be merged, a reviewer will do so as soon as 27 | possible. 28 | 29 | So far, here's our team of reviewers: 30 | 31 | * http://github.com/fredreichbier 32 | * http://github.com/fasterthanlime 33 | -------------------------------------------------------------------------------- /FAQ.rst: -------------------------------------------------------------------------------- 1 | A few questions 2 | --------------- 3 | 4 | Q: How did you bootstrap? 5 | A: From Java: http://github.com/nddrylliog/ooc It was a lot of fun and frustration 6 | Q: Do I need that j/ooc (java) version of the compiler to compile this? 7 | A: No. Let it die. We distribute rock as C sources now. (Remember, ooc 8 | usually compiles down to C) 9 | Q: If I don't need another ooc compiler to compile this one, how does it work? What does 'make bootstrap' do? 10 | A: 'make bootstrap' builds a rock binary from the C sources in build/c-source, 11 | calls it bin/c_rock, and uses it to recompile itself to bin/rock 12 | Q: I'm a naughty boy and I've read the Makefile. What does 'make prepare_bootstrap' do? 13 | A: It uses rock to generate the build/ directory, with -driver=make. Yes, it's awesome. 14 | Q: What platforms/OSes are supported? 15 | A: It has been tested on Gentoo, Ubuntu, Windows XP (with Mingw32 and GCC 4.4), and OSX. 16 | 'make prepare_bootstrap' may be shaky on Windows/OSX because of 17 | sed syntax differences (used to patch the produced build/Makefile). You're 18 | better off preparing bootstrap on a Linux, just like we do for source releases. 19 | 20 | 21 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | 2 | Note: make install does two things 3 | 1) Copy the manpage to /usr/local/man/man1 (override with MAN_INSTALL_PATH) 4 | 2) Create a symbolic link from bin/rock to /usr/bin/rock 5 | (override with PREFIX=/usr/local or BIN_INSTALL_PATH=~/bin) 6 | 7 | You have a -source release 8 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 | 10 | 'make && sudo make install' 11 | 12 | You have a binary release (e.g. rock-X.X.X-linux32, rock-X.X.X-win32, etc.) 13 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 14 | 15 | 'sudo make install' 16 | 17 | Troubleshooting 18 | --------------- 19 | 20 | Help! rock doesn't find its sdk! 21 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 22 | 23 | Here's how rock tries to find it: 24 | 25 | 1) If the ROCK_SDK environment variable is set, take that path 26 | 2) If the ROCK_DIST environment variable is set, take $ROCK_DIST/custom-sdk 27 | 3) If none of the above are set, tries to locate itself and tries ../custom-sdk 28 | (works if you've symlinked the rock executable to /usr/bin or something.) 29 | 30 | Help! rock doesn't find its libraries! 31 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32 | 33 | The only lib rock depends on is the Boehm GC (if you don't turn it off 34 | via -gc=off) 35 | 36 | We have static binary builds of the Boehm GC for most platforms/archs, 37 | look in rock/libs/ 38 | 39 | If we don't have your platform/arch, try to install the Boehm GC yourself, 40 | and compile with -gc=dynamic (it'll link with -lgc instead of the static 41 | binary builds) 42 | 43 | http://www.hpl.hp.com/personal/Hans_Boehm/gc/ 44 | 45 | Don't be afraid to open Makefile and build/Makefile 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2009-2016 Amos Wenger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/ooc-lang/rock.svg?branch=master)](https://travis-ci.org/ooc-lang/rock) 2 | 3 | # rock 4 | 5 | * [ooc](http://ooc-lang.org/) 6 | * [rock](https://github.com/ooc-lang/rock) 7 | 8 | rock is an ooc compiler written in ooc - in other words, it's 9 | where things begin to become really exciting. 10 | 11 | it has been bootstrapping since April 22, 2010 under Gentoo, Ubuntu, 12 | Arch Linux, Win32, OSX... 13 | 14 | ## Prerequisites 15 | 16 | You need the following packages when building rock: 17 | 18 | * GNU Make (`make` or `gmake`, depending on your operating system) 19 | * boehm-gc 20 | * tar (for extracting the C sources) 21 | * bzip2 (used by tar) 22 | 23 | ## Get started 24 | 25 | Run `make rescue` and you're good. 26 | 27 | ## Wait, what? 28 | 29 | `make rescue` downloads a set of C sources, compiles them, uses them to compile your copy of rock, 30 | and then uses that copy to recompile itself 31 | 32 | Then you'll have a 'rock' executable in bin/rock. Add it to your PATH, symlink it, copy it, just 33 | make sure it can find the SDK! 34 | 35 | ## Install 36 | 37 | See the `INSTALL` file 38 | 39 | To switch to the most recent git, read 40 | [ReleaseToGit](https://github.com/ooc-lang/rock/blob/master/docs/workflow/ReleaseToGit.md) 41 | 42 | ## License 43 | 44 | rock is distributed under the MIT license, see `LICENSE` for details. 45 | 46 | Boehm GC sources are vendored, it is distributed under an X11/MIT-like license, 47 | see `libs/sources/LICENSE` for details. 48 | -------------------------------------------------------------------------------- /docs/HOWTO: -------------------------------------------------------------------------------- 1 | Howto 2 | ===== 3 | 4 | How to create a manpage from this tasty rock.1.txt? Install asciidoc and run `a2x -f manpage rock.1.txt`. 5 | -------------------------------------------------------------------------------- /docs/internals/Metaclasses.md: -------------------------------------------------------------------------------- 1 | metaclasses 2 | =========== 3 | 4 | Classes without an explicit super-class inherit from Object. 5 | 6 | Dog: class {} 7 | d := Dog new() 8 | d instanceOf?(Object) // is true 9 | Dog inheritsFrom?(Object) // is true 10 | 11 | Every class has a meta-class. A class's meta-class inherit from 12 | its super-class's meta-class. 13 | 14 | E.g. if Dog extends Object, DogClass extends ObjectClass, etc. 15 | 16 | DogClass inheritsFrom?(ObjectClass) // is true 17 | 18 | navigating 19 | ---------- 20 | 21 | meta-classes mostly contain functions, and regular classes 22 | contain variables and such. 23 | 24 | You can check if you're in a meta-class with 'isMeta'. It's usually 25 | the case if you're here because of a FunctionDecl (e.g. in resolveCall) 26 | 27 | You can go from a class to its meta-class with getMeta(), and go back 28 | with getNonMeta() 29 | -------------------------------------------------------------------------------- /extensions/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all fancy-backtrace clean 2 | 3 | all: fancy-backtrace 4 | 5 | fancy-backtrace: 6 | cd fancy-backtrace && $(MAKE) 7 | 8 | clean: 9 | cd fancy-backtrace && $(MAKE) clean 10 | -------------------------------------------------------------------------------- /extensions/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Rock extensions 3 | 4 | Extensions are pieces of code not strictly necessary to ooc 5 | programs compilation and execution. However, some of them may 6 | be very useful. 7 | 8 | They typically have more dependencies than the rest of rock, 9 | which is why they live here - as a rule, once compiled, they 10 | should be easy to use, though. 11 | 12 | For information on each extension, refer to the extension-specific 13 | README. 14 | -------------------------------------------------------------------------------- /extensions/fancy-backtrace/.gitignore: -------------------------------------------------------------------------------- 1 | # Linux 2 | *.so 3 | 4 | # OSX 5 | *.dylib 6 | *.dSYM 7 | 8 | # Windows 9 | *.dll 10 | -------------------------------------------------------------------------------- /extensions/fancy-backtrace/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: all clean 3 | 4 | # try to determine the OS and architecture 5 | MYOS := $(shell uname -s) 6 | MACHINE := $(shell uname -m) 7 | ifeq ($(MYOS), Linux) 8 | ARCH=linux 9 | else ifeq ($(MYOS), FreeBSD) 10 | ARCH=freebsd 11 | else ifeq ($(MYOS), OpenBSD) 12 | ARCH=openbsd 13 | else ifeq ($(MYOS), NetBSD) 14 | ARCH=netbsd 15 | else ifeq ($(MYOS), DragonFly) 16 | ARCH=dragonfly 17 | else ifeq ($(MYOS), Darwin) 18 | ARCH=osx 19 | else ifeq ($(MYOS), CYGWIN_NT-5.1) 20 | ARCH=win 21 | else ifeq ($(MYOS), MINGW32_NT-5.1) 22 | ARCH=win 23 | else ifeq ($(MYOS), MINGW32_NT-6.1) 24 | ARCH=win 25 | else ifeq ($(MYOS),) 26 | ifeq (${OS}, Windows_NT) 27 | ARCH=win 28 | else 29 | $(error "OS ${OS} unrecognized - please open an issue at https://github.com/ooc-lang/rock/issues") 30 | endif 31 | endif 32 | 33 | ifeq ($(ARCH), win) 34 | MAKE_FILE=Makefile.win32 35 | else ifeq ($(ARCH), linux) 36 | MAKE_FILE=Makefile.linux 37 | else ifeq ($(ARCH), osx) 38 | MAKE_FILE=Makefile.osx 39 | else 40 | MAKE_FILE=Makefile.platform-unsupported 41 | endif 42 | 43 | build: 44 | BINDIR=../../bin $(MAKE) -f ${MAKE_FILE} build 45 | @echo "fancy-backtrace compiled!" 46 | 47 | clean: 48 | $(MAKE) -f ${MAKE_FILE} clean 49 | @echo "fancy-backtrace cleaned!" 50 | 51 | -------------------------------------------------------------------------------- /extensions/fancy-backtrace/Makefile.linux: -------------------------------------------------------------------------------- 1 | .PHONY: build check clean 2 | 3 | DEBUG_FLAGS := -g -rdynamic 4 | CC_FLAGS := -D_GNU_SOURCE $(DEBUG_FLAGS) 5 | LD_FLAGS := -lbfd -liberty -lz 6 | 7 | build : check fancy_backtrace.so 8 | cp fancy_backtrace.so ${BINDIR}/ 9 | 10 | fancy_backtrace.so : fancy_backtrace.c 11 | gcc $(CC_FLAGS) -DBUILDING_BACKTRACE_LIB -fPIC -O2 -shared -Wall -o $@ $^ $(LD_FLAGS) 12 | 13 | clean : 14 | @rm -f fancy_backtrace.so 15 | 16 | check : 17 | @echo "#include " | cpp -E - > /dev/null 2> /dev/null || \ 18 | (echo "[WARNING] binutils-dev missing! install it via 'apt-get install binutils-dev' or similar.") 19 | @echo "#include " | gcc -E - -o /tmp/zlibtest -lz > /dev/null 2> /dev/null || \ 20 | (echo "[WARNING] zlib missing! install it via 'apt-get install zlib1g-dev' or similar.") 21 | -------------------------------------------------------------------------------- /extensions/fancy-backtrace/Makefile.osx: -------------------------------------------------------------------------------- 1 | .PHONY: build check clean 2 | 3 | GETTEXT := $(shell brew info gettext | grep 'Cellar' | head -1 | cut -d ' ' -f 1) 4 | BINUTILS := $(shell brew info binutils | grep 'Cellar' | head -1 | cut -d ' ' -f 1) 5 | 6 | DEBUG_FLAGS := -fno-pie -g 7 | OSX_FLAGS := -I$(GETTEXT)/include -I$(BINUTILS)/include -L$(GETTEXT)/lib -L$(BINUTILS)/lib/ -L$(BINUTILS)/lib/x86_64/ 8 | 9 | build : check fancy_backtrace.dylib 10 | cp -rf fancy_backtrace.dylib* ${BINDIR}/ 11 | 12 | fancy_backtrace.dylib : fancy_backtrace.c 13 | gcc ${DEBUG_FLAGS} ${OSX_FLAGS} -DBUILDING_BACKTRACE_LIB -fPIC -O2 -shared -Wall -o $@ $^ -lbfd -lintl -liberty -lz 14 | 15 | clean : 16 | @rm -rf fancy_backtrace.dylib fancy_backtrace.dylib.dSYM 17 | 18 | check : 19 | ifeq ($(GETTEXT),) 20 | @echo "[WARNING] gettext not found! install it via 'brew install gettext'" 21 | @exit 1 22 | endif 23 | 24 | ifeq ($(BINUTILS),) 25 | @echo "[WARNING] binutils not found! install it via 'brew install binutils'" 26 | @exit 1 27 | endif 28 | -------------------------------------------------------------------------------- /extensions/fancy-backtrace/Makefile.unsupported: -------------------------------------------------------------------------------- 1 | 2 | build: 3 | @echo "fancy-backtrace unsupported on your platform." 4 | @exit 1 5 | -------------------------------------------------------------------------------- /extensions/fancy-backtrace/Makefile.win32: -------------------------------------------------------------------------------- 1 | .PHONY: build clean 2 | 3 | GCC ?= gcc 4 | 5 | # This is needed for some installs of MSYS/MinGW... don't ask. 6 | WIN_FLAGS:= -I/mingw/include -L/mingw/lib -I/usr/local/include -L/usr/local/lib 7 | 8 | MINGW64_PRESENT := $(shell echo __MINGW64__ | cpp -E - | tail -1) 9 | 10 | ifeq ($(MINGW64_PRESENT), 1) 11 | WIN_LINKER_FLAGS:= -lbfd -liberty -limagehlp -lz 12 | else 13 | WIN_LINKER_FLAGS:= -lbfd -liberty -lintl -limagehlp -lz 14 | endif 15 | 16 | build : fancy_backtrace.dll 17 | cp $^ ${BINDIR}/ 18 | 19 | fancy_backtrace.dll : fancy_backtrace.c 20 | $(GCC) $(WIN_FLAGS) -DBUILDING_BACKTRACE_LIB -O2 -shared -Wall -o $@ $^ $(WIN_LINKER_FLAGS) 21 | 22 | clean : 23 | @rm -f fancy_backtrace.dll 24 | 25 | -------------------------------------------------------------------------------- /pcre.use: -------------------------------------------------------------------------------- 1 | Name: PCRE 2 | Description: Perl Compatible Regular Expressions 3 | Pkgs: libpcre 4 | Includes: pcre.h 5 | -------------------------------------------------------------------------------- /rock.use: -------------------------------------------------------------------------------- 1 | Name: rock 2 | Version: head 3 | Origin: git://github.com/ooc-lang/rock.git 4 | Description: ooc compiler written in ooc 5 | SourcePath: source 6 | 7 | Main: rock/rock.ooc 8 | 9 | # greg-generated grammar 10 | Additionals: ./source/rock/frontend/NagaQueen.c 11 | -------------------------------------------------------------------------------- /sdk-dynlib.use: -------------------------------------------------------------------------------- 1 | Name: sdk-dynlib 2 | Description: dynamic library loading component of the ooc standard library 3 | 4 | version (linux) { 5 | # Under Linux, we need to link with libdl explicitly 6 | # OSX and Windows are fine on that front (go figure). 7 | Libs: -ldl 8 | } 9 | 10 | -------------------------------------------------------------------------------- /sdk-net.use: -------------------------------------------------------------------------------- 1 | Name: sdk-net 2 | Description: net component of the ooc standard library 3 | 4 | version (windows) { 5 | # Under MinGW, we need that lib to use winsock 6 | Libs: -lws2_32 7 | } 8 | -------------------------------------------------------------------------------- /sdk.use: -------------------------------------------------------------------------------- 1 | Name: sdk 2 | Description: ooc standard library 3 | SourcePath: sdk 4 | Imports: lang/Abstractions, lang/Buffer, lang/BufferIterator, lang/Character, lang/Exception, lang/Format, lang/IO, lang/Iterators, lang/Memory, lang/Numbers, lang/String, lang/stdlib, lang/types, lang/VarArgs 5 | 6 | AndroidLibs: gc 7 | AndroidIncludePaths: ../gc/include 8 | -------------------------------------------------------------------------------- /sdk/io/StringReader.ooc: -------------------------------------------------------------------------------- 1 | import BufferReader 2 | 3 | StringReader: class extends BufferReader { 4 | string: String 5 | 6 | init: func ~withString (=string) { 7 | super(string _buffer) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /sdk/lang/Abstractions.ooc: -------------------------------------------------------------------------------- 1 | loop: func(f: Func -> Bool) { 2 | while(f()) {} 3 | } 4 | -------------------------------------------------------------------------------- /sdk/lang/Array.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef ___lang_array___ 3 | #define ___lang_array___ 4 | 5 | #ifdef __OOC_USE_GC__ 6 | #define array_malloc GC_malloc 7 | #define array_free GC_free 8 | #else 9 | #define array_malloc(size) calloc(1, (size)) 10 | #define array_free free 11 | #endif // GC 12 | 13 | #include 14 | 15 | 16 | #define _lang_array__Array_new(type, size) ((_lang_array__Array) { size, array_malloc((size) * sizeof(type)) }); 17 | 18 | #define _lang_array__Array_get(array, index, type) ( \ 19 | (index < 0 || index >= array.length) ? \ 20 | lang_Exception__Exception_throw((lang_Exception__Exception *) lang_Exception__OutOfBoundsException_new_noOrigin(index, array.length)), \ 21 | *((type*) array.data) : \ 22 | ((type*) array.data)[index]) 23 | 24 | #define _lang_array__Array_set(array, index, type, value) \ 25 | (index < 0 || index >= array.length) ? \ 26 | lang_Exception__Exception_throw((lang_Exception__Exception *) lang_Exception__OutOfBoundsException_new_noOrigin(index, array.length)), \ 27 | *((type*) array.data) : \ 28 | (((type*) array.data)[index] = value) 29 | 30 | #define _lang_array__Array_free(array) { array_free(array.data) } 31 | 32 | typedef struct { 33 | size_t length; 34 | void* data; 35 | } _lang_array__Array; 36 | 37 | #endif // ___lang_array___ 38 | 39 | -------------------------------------------------------------------------------- /sdk/lang/BufferIterator.ooc: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * iterators 4 | */ 5 | BufferIterator: class extends BackIterator { 6 | 7 | i := 0 8 | str: Buffer 9 | 10 | init: func ~withStr (=str) {} 11 | 12 | hasNext?: func -> Bool { 13 | i < str size 14 | } 15 | 16 | next: func -> T { 17 | c := (str data + i)@ 18 | i += 1 19 | return c 20 | } 21 | 22 | hasPrev?: func -> Bool { 23 | i > 0 24 | } 25 | 26 | prev: func -> T { 27 | i -= 1 28 | return (str data + i)@ 29 | } 30 | 31 | remove: func -> Bool { false } // this could be implemented! 32 | 33 | } 34 | -------------------------------------------------------------------------------- /sdk/lang/stdlib.ooc: -------------------------------------------------------------------------------- 1 | include stdlib 2 | 3 | exit: extern func (Int) 4 | EXIT_SUCCESS: extern const Int 5 | EXIT_FAILURE: extern const Int 6 | 7 | atexit: extern func (Pointer) 8 | 9 | -------------------------------------------------------------------------------- /sdk/math.use: -------------------------------------------------------------------------------- 1 | Name: math 2 | Description: math lib 3 | Libs: -lm 4 | -------------------------------------------------------------------------------- /sdk/native/win32/errors.ooc: -------------------------------------------------------------------------------- 1 | 2 | version(windows) { 3 | 4 | import native/win32/types 5 | 6 | include windows 7 | 8 | GetLastError: extern func -> Int 9 | 10 | ERROR_HANDLE_EOF: extern Int 11 | 12 | FormatMessage: extern func(dwFlags: DWORD, lpSource: Pointer, dwMessageId: DWORD, dwLanguageId: DWORD, 13 | lpBuffer: LPTSTR, nSize: DWORD, Arguments: VaList*) -> DWORD 14 | 15 | FORMAT_MESSAGE_FROM_SYSTEM: extern Long 16 | FORMAT_MESSAGE_IGNORE_INSERTS: extern Long 17 | FORMAT_MESSAGE_ARGUMENT_ARRAY: extern Long 18 | 19 | GetWindowsErrorMessage: func (err: DWORD) -> String { 20 | BUF_SIZE := 256 21 | buf := Buffer new(BUF_SIZE) 22 | len: SSizeT = FormatMessage( 23 | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY, 24 | null, 25 | err, 26 | 0, 27 | buf data as CString, 28 | BUF_SIZE, 29 | null 30 | ) 31 | buf setLength(len) 32 | 33 | // rip away trailing CR LF TAB SPACES etc. 34 | while ((len > 0) && (buf[len - 1] as Octet < 32)) len -= 1 35 | buf setLength(len) 36 | buf toString() 37 | } 38 | 39 | WindowsException: class extends Exception { 40 | init: func (.origin, err: Long) { 41 | super(origin, GetWindowsErrorMessage(err)) 42 | } 43 | 44 | init: func ~withMsg (.origin, err: Long, message: String) { 45 | super(origin, "%s: %s" format(message, GetWindowsErrorMessage(err))) 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /sdk/net/Exceptions.ooc: -------------------------------------------------------------------------------- 1 | /** 2 | Base exception which all networking errors extend. 3 | */ 4 | NetError: class extends OSException { 5 | init: func { super() } 6 | init: func ~message (.message) { super(message) } 7 | init: func ~originMessage (.origin, .message) { super(origin, message) } 8 | } 9 | 10 | /** 11 | The address string provided is invalid. 12 | */ 13 | InvalidAddress: class extends NetError { 14 | init: func { super() } 15 | init: func ~message (.message) { super(message) } 16 | init: func ~originMessage (.origin, .message) { super(origin, message) } 17 | } 18 | 19 | /** 20 | A DNS error occured while performing a lookup. 21 | */ 22 | DNSError: class extends NetError { 23 | init: func { super() } 24 | init: func ~message (.message) { super(message) } 25 | init: func ~originMessage (.origin, .message) { super(origin, message) } 26 | } 27 | 28 | /** 29 | A Socket error occured. 30 | */ 31 | SocketError: class extends NetError { 32 | init: func { super() } 33 | init: func ~message (.message) { super(message) } 34 | init: func ~originMessage (.origin, .message) { super(origin, message) } 35 | } 36 | 37 | /** 38 | A Timeout occored. 39 | */ 40 | TimeoutError: class extends NetError { 41 | init: func { super() } 42 | init: func ~message (.message) { super(message) } 43 | init: func ~originMessage (.origin, .message) { super(origin, message) } 44 | } 45 | -------------------------------------------------------------------------------- /sdk/os/Coro.ooc: -------------------------------------------------------------------------------- 1 | import native/[CoroUnix, CoroWin32] 2 | 3 | /** 4 | * Portable ucontext/fiber-based coroutines implementation for cooperative multitasking. 5 | * 6 | * Based on the work of: 7 | * - Steve Dekorte (libcoroutine - http://github.com/stevedekorte/coroutine) 8 | * - Russ Cox (libcoroutine OSX10.6 fixes) 9 | * - Edgar Toernig (Minimalistic cooperative multitasking - http://www.goron.de/~froese/) 10 | */ 11 | Coro: abstract class { 12 | // 128k stack is enough room for quite a few function calls 13 | DEFAULT_STACK_SIZE := static 128 * 1_024 14 | 15 | isMain := false 16 | 17 | new: static func -> This { 18 | version((unix && !openbsd) || apple) { 19 | return CoroUnix new() as This 20 | } 21 | version(windows) { 22 | return CoroWin32 new() as This 23 | } 24 | raise("os/Coro is unsupported on your platform!") 25 | null 26 | } 27 | 28 | /// Marks that this Coro is a main coro (cannot yield) 29 | initializeMainCoro: func { 30 | isMain = true 31 | } 32 | 33 | /// Starts a child Coro that executes the callback 34 | startCoro: abstract func(other: This, callback: Func) 35 | 36 | /// Sets up a child Coro 37 | setup: abstract func(other: This, callback: Func) 38 | 39 | /// Switches execution to another Coro 40 | switchTo: abstract func(next: This) 41 | 42 | /// Yields execution to the Coro that spawned this 43 | yield: abstract func 44 | 45 | /// Frees non-GC memory that the Coro may have allocated (e.g. stack memory) 46 | free: abstract func 47 | } 48 | -------------------------------------------------------------------------------- /sdk/os/unistd.ooc: -------------------------------------------------------------------------------- 1 | include unistd | (__USE_GNU) 2 | 3 | /* Functions */ 4 | chdir: extern func(CString) -> Int 5 | dup2: extern func(Int, Int) -> Int 6 | execv: extern func(CString, CString*) -> Int 7 | execvp: extern func(CString, CString*) -> Int 8 | execve: extern func(CString, CString*, CString*) -> Int 9 | fileno: extern func(FILE*) -> Int 10 | fork: extern func -> Int 11 | getpid: extern func -> UInt 12 | pipe: extern func(arg: Int*) -> Int 13 | isatty: extern func(fd: Int) -> Int 14 | gethostname: extern func(localSystemName: CString, localSystemNameLength: SizeT) -> Int 15 | -------------------------------------------------------------------------------- /sdk/os/wait.ooc: -------------------------------------------------------------------------------- 1 | version(unix || apple) { 2 | include sys/wait 3 | } 4 | 5 | /* Constants */ 6 | WEXITSTATUS: extern func (Int) -> Int 7 | WIFEXITED: extern func (Int) -> Int 8 | WIFSIGNALED: extern func (Int) -> Int 9 | WTERMSIG: extern func (Int) -> Int 10 | 11 | /* Functions */ 12 | /* status: Int* */ 13 | wait: extern func(Int*) -> Int 14 | /* pid: Int, status: Int, options: Int */ 15 | waitpid: extern func(Int, Int*, Int) -> Int 16 | 17 | 18 | -------------------------------------------------------------------------------- /sdk/siphash.use: -------------------------------------------------------------------------------- 1 | Name: siphash 2 | Description: SipHash implementation in C 3 | SourcePath: hash 4 | Imports: siphash 5 | Additionals: ./hash/csiphash.c 6 | -------------------------------------------------------------------------------- /sdk/structs/Stick.ooc: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * A Stick is like a BagStack, ie. it can contain any type - but 4 | * it provides no safety at all, ie. you have to know the types of 5 | * what you put in it in order to be able to push it back. 6 | */ 7 | Stick: class { 8 | 9 | base, current: Octet* 10 | capacity: Int // in octets 11 | 12 | init: func (=capacity) { 13 | base = gc_malloc(capacity) 14 | current = base 15 | } 16 | 17 | push: func (element: T) { 18 | if((current - base + T size) as Int > capacity) { 19 | Exception new(This, "Pushing beyond stick limits!") throw() 20 | } 21 | 22 | memcpy(current, element, T size) 23 | current += T size 24 | } 25 | 26 | pop: func (T: Class) -> T { 27 | current -= T size 28 | ret: T 29 | memcpy(ret&, current, T size) 30 | return ret 31 | } 32 | 33 | seek: func (index: Int) { 34 | current = base + index 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /sdk/text/json.ooc: -------------------------------------------------------------------------------- 1 | /* 2 | A wrapper module for text/json/[Parser,Generator] that doesn't 3 | pollute the global namespace when imported normally. 4 | This module provides a `JSON` class with static methods. 5 | */ 6 | import io/[Reader,Writer], structs/HashBag 7 | import json/[Generator,Parser] into _JSON 8 | 9 | JSON: class { 10 | parse: static func ~hashbag (reader: Reader) -> HashBag { 11 | _JSON parse(reader, HashBag) 12 | } 13 | 14 | parse: static func (reader: Reader, T: Class) -> T { 15 | _JSON parse(reader, T) 16 | } 17 | 18 | parse: static func ~hashbagString (s: String) -> HashBag { 19 | _JSON parse(s, HashBag) 20 | } 21 | 22 | parse: static func ~string (s: String, T: Class) -> T { 23 | _JSON parse(s, T) 24 | } 25 | 26 | generate: static func (w: Writer, obj: T) { 27 | _JSON generate(w, obj) 28 | } 29 | 30 | generateString: static func (obj: T) -> String { 31 | _JSON generateString(obj) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sdk/text/json/DSL.ooc: -------------------------------------------------------------------------------- 1 | import structs/[Bag, HashBag] 2 | 3 | import Generator 4 | 5 | DSL: class { // TODO: make this a singleton. or so. 6 | 7 | init: func 8 | 9 | json: func (f: Func(This) -> HashBag) -> String { 10 | generateString(f(this)) 11 | } 12 | 13 | object: func (args: ...) -> HashBag { 14 | object := HashBag new() 15 | keyFollowing := true 16 | key: String = null 17 | args each(|arg| 18 | match(keyFollowing) { 19 | case true => { 20 | if(T != String) { 21 | Exception new(This, "Key is not a String, but %s." format(T name)) throw() 22 | } else { 23 | key = arg as String 24 | } 25 | keyFollowing = false 26 | } 27 | case false => { 28 | object put(key, arg) 29 | keyFollowing = true 30 | } 31 | } 32 | ) 33 | object 34 | } 35 | 36 | array: func (args: ...) -> Bag { 37 | bag := Bag new() 38 | args each(|arg| 39 | bag add(arg) 40 | ) 41 | bag 42 | } 43 | } 44 | 45 | make: func (f: Func(DSL) -> HashBag) -> String { 46 | DSL new() json(f) // TODO: not so nice 47 | } 48 | 49 | -------------------------------------------------------------------------------- /sdk/threading/native/ThreadLocalUnix.ooc: -------------------------------------------------------------------------------- 1 | import structs/HashMap 2 | import ../Thread, ThreadUnix 3 | include unistd 4 | 5 | version(unix || apple) { 6 | include pthread 7 | 8 | pthread_self: extern func -> PThread 9 | 10 | ThreadLocalUnix: class extends ThreadLocal { 11 | values := HashMap new() 12 | valuesMutex := Mutex new() 13 | 14 | init: func ~unix { 15 | 16 | } 17 | 18 | set: func (value: T) { 19 | valuesMutex lock() 20 | values put(pthread_self(), value) 21 | valuesMutex unlock() 22 | } 23 | 24 | get: func -> T { 25 | valuesMutex lock() 26 | value := values get(pthread_self()) 27 | valuesMutex unlock() 28 | value 29 | } 30 | 31 | hasValue?: func -> Bool { 32 | valuesMutex lock() 33 | has := values contains?(pthread_self()) 34 | valuesMutex unlock() 35 | has 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sdk/threading/native/ThreadLocalWin32.ooc: -------------------------------------------------------------------------------- 1 | import structs/HashMap 2 | import ../Thread, ThreadWin32 3 | include unistd 4 | 5 | version(windows) { 6 | include windows 7 | 8 | GetCurrentThreadId: extern func -> Long // TODO: also laziness. 9 | 10 | ThreadLocalWin32: class extends ThreadLocal { 11 | values := HashMap new() 12 | valuesMutex := Mutex new() 13 | 14 | init: func ~windows { 15 | 16 | } 17 | 18 | set: func (value: T) { 19 | valuesMutex lock() 20 | values put(GetCurrentThreadId(), value) 21 | valuesMutex unlock() 22 | } 23 | 24 | get: func -> T { 25 | valuesMutex lock() 26 | value := values get(GetCurrentThreadId()) 27 | valuesMutex unlock() 28 | value 29 | } 30 | 31 | hasValue?: func -> Bool { 32 | valuesMutex lock() 33 | has := values contains?(GetCurrentThreadId()) 34 | valuesMutex unlock() 35 | has 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /source/rock/RockVersion.ooc: -------------------------------------------------------------------------------- 1 | 2 | RockVersion: class { 3 | execName := static "" 4 | 5 | getMajor: static func -> Int { 0 } 6 | getMinor: static func -> Int { 9 } 7 | getPatch: static func -> Int { 11 } 8 | getRevision: static func -> String { "head" } 9 | getCodename: static func -> String { "sapporo" } 10 | 11 | getName: static func -> String { "%d.%d.%d%s codename %s" format( 12 | getMajor(), getMinor(), getPatch(), (getRevision() ? "-" + getRevision() : ""), 13 | getCodename()) } 14 | } 15 | -------------------------------------------------------------------------------- /source/rock/backend/cnaughty/AwesomeWriter.ooc: -------------------------------------------------------------------------------- 1 | import io/[Writer], ../../io/TabbedWriter 2 | import ../../middle/[Visitor, Node] 3 | 4 | /** 5 | * Extension of TabbedWriter that allows to handle 6 | * blocks opening/closing and appending of nodes. 7 | */ 8 | AwesomeWriter: class extends TabbedWriter { 9 | 10 | visitor: Visitor 11 | 12 | init: func ~awesome (=visitor, .stream) { 13 | super(stream) 14 | } 15 | 16 | app: func ~node (node: Node) { 17 | node accept(visitor) 18 | } 19 | 20 | openBlock: func { 21 | this app("{"). tab() 22 | } 23 | 24 | closeBlock: func { 25 | this untab(). nl(). app("}") 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /source/rock/backend/cnaughty/EnumDeclWriter.ooc: -------------------------------------------------------------------------------- 1 | 2 | import ../../middle/EnumDecl 3 | import Skeleton 4 | 5 | EnumDeclWriter: abstract class extends Skeleton { 6 | 7 | writeTypedef: static func (this: Skeleton, eDecl: EnumDecl) { 8 | current = fw 9 | 10 | // extern EnumDecls shouldn't print a typedef. 11 | if(!eDecl isExtern()) { 12 | current nl(). app("typedef int "). app(eDecl underName()). app(';') 13 | } 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /source/rock/backend/cnaughty/InterfaceDeclWriter.ooc: -------------------------------------------------------------------------------- 1 | import ClassDeclWriter, CoverDeclWriter, CGenerator, Skeleton 2 | import ../../middle/[InterfaceDecl] 3 | 4 | InterfaceDeclWriter: abstract class extends Skeleton { 5 | 6 | write: static func ~_interface (this: Skeleton, iDecl: InterfaceDecl) { 7 | 8 | ClassDeclWriter write(this, iDecl) 9 | 10 | current = fw 11 | CoverDeclWriter writeGuts(this, iDecl getFatType()) 12 | 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /source/rock/backend/cnaughty/Skeleton.ooc: -------------------------------------------------------------------------------- 1 | import AwesomeWriter, ../../middle/[Visitor, Statement, ControlStatement] 2 | import text/EscapeSequence, rock/frontend/BuildParams, io/File 3 | 4 | Skeleton: abstract class extends Visitor { 5 | 6 | STRING_CONSTRUCTOR := static const "(void*) lang_String__makeStringLiteral(\"%s\", %d)" 7 | 8 | params: BuildParams 9 | module: Module 10 | 11 | hw, cw, fw, current: AwesomeWriter 12 | 13 | /** Write a line */ 14 | writeLine: func (stat: Statement) { 15 | if(params debug?() && params lineDirectives) { 16 | if(!stat token module) stat token module = module 17 | 18 | current nl(). app("#line "). app(stat token getLineNumber() toString()). app(" \""). app(EscapeSequence escape(stat token getPath())). app("\"") 19 | } 20 | 21 | current nl(). app(stat) 22 | if(!stat instanceOf?(ControlStatement)) 23 | current app(';') 24 | } 25 | 26 | writeStringLiteral: func (value: String, raw?: Bool = false) { 27 | if(raw?) { 28 | current app('"'). app(value). app('"') 29 | } else { 30 | current app(STRING_CONSTRUCTOR format(value, EscapeSequence unescape(value) length())) 31 | } 32 | } 33 | 34 | writeGcInit: func { 35 | current nl(). app("#ifdef __ANDROID__"); 36 | current nl(). app("GC_init();") 37 | current nl(). app("#else"); 38 | current nl(). app("GC_INIT();") 39 | current nl(). app("#endif") 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /source/rock/backend/cnaughty/TypeWriter.ooc: -------------------------------------------------------------------------------- 1 | import structs/[List, ArrayList, HashMap] 2 | import ../../middle/[Type, InterfaceDecl, TypeDecl] 3 | import Skeleton 4 | 5 | TypeWriter: abstract class extends Skeleton { 6 | 7 | write: static func ~_type (this: Skeleton, type: Type) { 8 | 9 | current app(type toString()) 10 | 11 | } 12 | 13 | writeSpaced: static func (this: Skeleton, type: Type, doPrefix: Bool) { 14 | 15 | write(this, type) 16 | current app(' ') 17 | 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /source/rock/backend/cnaughty/VersionWriter.ooc: -------------------------------------------------------------------------------- 1 | import ../../middle/[Version] 2 | import Skeleton 3 | 4 | VersionWriter: abstract class extends Skeleton { 5 | 6 | writeStart: static func ~_version (this: Skeleton, _version: VersionSpec) { 7 | if (_version spec && _version spec prelude) { 8 | current nl(). app(_version spec prelude) 9 | } 10 | current nl(). app("#if ") 11 | _version write(current) 12 | } 13 | 14 | writeEnd: static func ~_version (this: Skeleton, _version: VersionSpec) { 15 | current nl(). app("#endif") 16 | if (_version spec && _version spec afterword) { 17 | current nl(). app(_version spec afterword) 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /source/rock/frontend/drivers/DummyDriver.ooc: -------------------------------------------------------------------------------- 1 | 2 | // sdk stuff 3 | import io/File 4 | import structs/[List, ArrayList] 5 | 6 | // our stuff 7 | import Driver 8 | 9 | import rock/frontend/[BuildParams, Target] 10 | import rock/middle/Module 11 | import rock/backend/cnaughty/CGenerator 12 | 13 | /** 14 | * Dummy driver, which only generates the .c source code 15 | * 16 | * Use it with -onlygen or -driver=dummy 17 | */ 18 | DummyDriver: class extends Driver { 19 | 20 | init: func (.params) { 21 | super(params) 22 | 23 | // Generating the sources is the *whole point* of onlygen. 24 | params clean = false 25 | 26 | // Don't do lib-caching, we don't want things in .libs/ 27 | params libcache = false 28 | } 29 | 30 | compile: func (module: Module) -> Int { 31 | 32 | params outPath mkdirs() 33 | for(candidate in module collectDeps()) { 34 | CGenerator new(params, candidate) write() 35 | } 36 | 37 | copyLocals(module, params) 38 | 39 | if (params verbose) { 40 | "Generated sources in %s, enjoy!" format(params outPath path) println() 41 | } 42 | 43 | 0 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /source/rock/frontend/pkgconfig/PkgInfo.ooc: -------------------------------------------------------------------------------- 1 | 2 | // sdk stuff 3 | import structs/[ArrayList, List] 4 | import text/StringTokenizer 5 | 6 | /** 7 | * Information about a package managed by pkg-config 8 | */ 9 | PkgInfo: class { 10 | 11 | /** The name of the package, e.g. gtk+-2.0, or imlib2 */ 12 | name: String 13 | 14 | /** The output of `pkg-config --cflags name` */ 15 | compilerFlags := ArrayList new() 16 | 17 | /** The output of `pkg-config --libs name` */ 18 | linkerFlags := ArrayList new() 19 | 20 | init: func (=name, libsString, cflagsString: String) { 21 | compilerFlags addAll(split(cflagsString)) 22 | linkerFlags addAll(split(libsString)) 23 | } 24 | 25 | split: func (line: String) -> List { 26 | line split(' ', false) \ 27 | map(|f| f trim(" \t")) \ 28 | filter(|f| !f empty?()) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /source/rock/io/CachedFileWriter.ooc: -------------------------------------------------------------------------------- 1 | import io/[BufferReader, BufferWriter, File], structs/HashMap 2 | 3 | /** 4 | Cached file writer. 5 | 6 | Similar to a FileWriter, but only writes the file on closing, if 7 | it's different from an already-existing file, of if the target 8 | file doesn't eixst at all. 9 | */ 10 | CachedFileWriter: class extends BufferWriter { 11 | 12 | file: File 13 | 14 | init: func ~withFile(=file) { 15 | super() 16 | } 17 | 18 | init: func ~withPath(path: String) { 19 | init(File new(path)) 20 | } 21 | 22 | write: func(chars: Char*, length: SizeT) -> SizeT { 23 | super(chars, length) 24 | } 25 | 26 | close: func { 27 | flushAndClose() 28 | } 29 | 30 | /** 31 | * :return: true if the file was really written to disk 32 | * (ie. if it was different from what was on-disk), false 33 | * if nothing was touched. 34 | */ 35 | flushAndClose: func -> Bool { 36 | if(file exists?()) { 37 | thisContent := buffer toString() 38 | fileContent := file read() 39 | 40 | hash1 := ac_X31_hash(thisContent) 41 | hash2 := ac_X31_hash(fileContent) 42 | 43 | if(hash1 == hash2) { 44 | // same hash? don't rewrite. 45 | return false 46 | } 47 | } 48 | 49 | file write(BufferReader new(buffer)) 50 | true 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /source/rock/middle/ArrayCreation.ooc: -------------------------------------------------------------------------------- 1 | import Type, Expression, Visitor, Node 2 | 3 | import tinker/[Trail, Resolver, Response] 4 | 5 | ArrayCreation: class extends Expression { 6 | 7 | expr: Expression = null /* assigned in ArrayAccess */ 8 | literal? := false /* used to signify this array is created by a literal and skip some code generation */ 9 | arrayType, realType : ArrayType 10 | 11 | init: func ~withLiteral (.arrayType, =literal?, .token) { 12 | init(arrayType, token) 13 | } 14 | 15 | init: func ~arrayCrea (=arrayType, .token) { 16 | super(token) 17 | realType = arrayType exprLessClone() 18 | } 19 | 20 | clone: func -> This { 21 | copy := new(arrayType, token) 22 | copy expr = expr ? expr clone() : null 23 | copy 24 | } 25 | 26 | accept: func (visitor: Visitor) { 27 | visitor visitArrayCreation(this) 28 | } 29 | 30 | resolve: func (trail: Trail, res: Resolver) -> Response { 31 | if(!arrayType resolve(trail, res) ok()) { 32 | return Response LOOP 33 | } 34 | 35 | if(!realType resolve(trail, res) ok()) { 36 | return Response LOOP 37 | } 38 | 39 | return Response OK 40 | } 41 | 42 | replace: func (oldie, kiddo: Node) -> Bool { 43 | if(oldie == arrayType) { 44 | oldie = kiddo as ArrayType 45 | return true 46 | } 47 | false 48 | } 49 | 50 | toString: func -> String { 51 | "%s new()" format(arrayType toString()) 52 | } 53 | 54 | getType: func -> Type { 55 | realType 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /source/rock/middle/Block.ooc: -------------------------------------------------------------------------------- 1 | import ControlStatement, Visitor, Scope 2 | 3 | /** 4 | * A simple block 5 | */ 6 | Block: class extends ControlStatement { 7 | 8 | init: func (.token) { super(token) } 9 | 10 | accept: func (v: Visitor) { v visitBlock(this) } 11 | 12 | isDeadEnd: func -> Bool { true } 13 | 14 | clone: func -> This { 15 | copy := new(token) 16 | body list each(|stat| copy body add(stat clone())) 17 | copy 18 | } 19 | 20 | toString: func -> String { getBody() toString() } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /source/rock/middle/BoolLiteral.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Literal, Visitor, Type, BaseType 3 | 4 | BoolLiteral: class extends Literal { 5 | 6 | value: Bool 7 | type := static BaseType new("Bool", nullToken) 8 | 9 | init: func ~boolLiteral (=value, .token) { 10 | super(token) 11 | } 12 | 13 | clone: func -> This { new(value, token) } 14 | 15 | accept: func (visitor: Visitor) { visitor visitBoolLiteral(this) } 16 | 17 | getType: func -> Type { type } 18 | getValue: func -> Bool { value } 19 | 20 | toString: func -> String { 21 | value ? "true" : "false" 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /source/rock/middle/CharLiteral.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Literal, Visitor, Type, BaseType 3 | 4 | CharLiteral: class extends Literal { 5 | 6 | // TODO: maybe the value should be a char? then we'd need escape/unescape code. 7 | // j/ooc does that. I'm not sure it's too useful 8 | value: String 9 | type := static BaseType new("Char", nullToken) 10 | 11 | init: func ~charLiteral (=value, .token) { 12 | super(token) 13 | } 14 | 15 | clone: func -> This { new(value, token) } 16 | 17 | accept: func (visitor: Visitor) { visitor visitCharLiteral(this) } 18 | 19 | getType: func -> Type { type } 20 | 21 | toString: func -> String { 22 | "'" + value + "'" 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /source/rock/middle/Conditional.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import ControlStatement, Expression, Node 3 | import tinker/[Trail, Resolver, Response] 4 | 5 | Conditional: abstract class extends ControlStatement { 6 | 7 | condition: Expression 8 | 9 | init: func ~conditional (=condition, .token) { super(token) } 10 | 11 | resolve: func (trail: Trail, res: Resolver) -> Response { 12 | 13 | if(condition != null) { 14 | trail push(this) 15 | response := condition resolve(trail, res) 16 | trail pop(this) 17 | if(!response ok()) { 18 | return response 19 | } 20 | } 21 | 22 | return super(trail, res) 23 | 24 | } 25 | 26 | replace: func (oldie, kiddo: Node) -> Bool { 27 | if(oldie == condition) { 28 | condition = kiddo 29 | return true 30 | } 31 | 32 | return super(oldie, kiddo) 33 | } 34 | 35 | isDeadEnd: func -> Bool { true } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /source/rock/middle/Declaration.ooc: -------------------------------------------------------------------------------- 1 | import Expression, VariableDecl 2 | 3 | Declaration: abstract class extends Expression { 4 | 5 | init: func ~declaration (.token) { super(token) } 6 | 7 | addTypeArg: func (typeArg: VariableDecl) -> Bool { false } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /source/rock/middle/Dereference.ooc: -------------------------------------------------------------------------------- 1 | import structs/ArrayList 2 | import ../frontend/Token 3 | import Expression, Visitor, Type, Node 4 | import tinker/[Trail, Resolver, Response] 5 | 6 | Dereference: class extends Expression { 7 | 8 | expr: Expression 9 | 10 | init: func ~addressOf (=expr, .token) { 11 | super(token) 12 | } 13 | 14 | clone: func -> This { 15 | new(expr clone(), token) 16 | } 17 | 18 | accept: func (visitor: Visitor) { 19 | visitor visitDereference(this) 20 | } 21 | 22 | getGenericOperand: func -> Expression { 23 | if(expr getType() isGeneric() && expr getType() pointerLevel() > 0) { 24 | return expr 25 | } 26 | return super() 27 | } 28 | 29 | getType: func -> Type { expr getType() ? expr getType() dereference() : null } 30 | 31 | toString: func -> String { 32 | return expr toString() + "@" 33 | } 34 | 35 | resolve: func (trail: Trail, res: Resolver) -> Response { 36 | 37 | trail push(this) 38 | { 39 | response := expr resolve(trail, res) 40 | if(!response ok()) { 41 | trail pop(this) 42 | return response 43 | } 44 | } 45 | trail pop(this) 46 | 47 | return Response OK 48 | 49 | } 50 | 51 | replace: func (oldie, kiddo: Node) -> Bool { 52 | match oldie { 53 | case expr => expr = kiddo; true 54 | case => false 55 | } 56 | } 57 | 58 | isReferencable: func -> Bool { true } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /source/rock/middle/Else.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Conditional, Expression, If, Node, Scope, Statement, Visitor 3 | import tinker/[Errors, Resolver, Response, Trail] 4 | 5 | Else: class extends Conditional { 6 | 7 | init: func ~_else (.token) { super(null, token) } 8 | 9 | clone: func -> This { 10 | copy := new(token) 11 | body list each(|e| copy body add(e clone())) 12 | copy 13 | } 14 | 15 | accept: func (visitor: Visitor) { 16 | visitor visitElse(this) 17 | } 18 | 19 | toString: func -> String { 20 | "else " + body toString() 21 | } 22 | 23 | resolve: func(trail: Trail, res: Resolver) -> Response { 24 | trail push(this) 25 | response := body resolve(trail, res) 26 | trail pop(this) 27 | return response 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /source/rock/middle/Expression.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Statement, Type, AddressOf 3 | 4 | Expression: abstract class extends Statement { 5 | 6 | init: func(.token) { super(token) } 7 | 8 | getType: abstract func -> Type 9 | 10 | isReferencable: func -> Bool { false } 11 | 12 | getGenericOperand: func -> Expression { 13 | getType() isGeneric() ? this : AddressOf new(this, token) 14 | } 15 | 16 | clone: abstract func -> This 17 | 18 | } 19 | -------------------------------------------------------------------------------- /source/rock/middle/FlowControl.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Statement, While, Foreach, Visitor, Node 3 | import tinker/[Trail, Resolver, Response, Errors] 4 | 5 | FlowAction: enum { 6 | _break 7 | _continue 8 | 9 | toString: func -> String { 10 | match(this) { 11 | case This _break => "break" 12 | case This _continue => "continue" 13 | case => "no-op" 14 | } 15 | } 16 | } 17 | 18 | FlowControl: class extends Statement { 19 | action : FlowAction 20 | 21 | init: func ~match_ (=action, .token) { 22 | super(token) 23 | } 24 | 25 | clone: func -> This { 26 | new(action, token) 27 | } 28 | 29 | getAction: func -> FlowAction { action } 30 | 31 | accept: func (visitor: Visitor) { 32 | visitor visitFlowControl(this) 33 | } 34 | 35 | replace: func (oldie, kiddo: Node) -> Bool { false } 36 | 37 | resolve: func (trail: Trail, res: Resolver) -> Response { 38 | // Make sure we are either in a while of foreach statement 39 | if(trail find(While) == -1 && trail find(Foreach) == -1) { 40 | res throwError(InvalidFlowControl new(token, "Invalid use of %s outside of a loop" format(action toString()))) 41 | } 42 | 43 | Response OK 44 | } 45 | 46 | toString: func -> String { 47 | action toString() 48 | } 49 | } 50 | 51 | InvalidFlowControl: class extends Error { 52 | init: super func ~tokenMessage 53 | } 54 | -------------------------------------------------------------------------------- /source/rock/middle/If.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Conditional, Expression, Visitor, Else 3 | import tinker/[Trail, Resolver, Response, Errors] 4 | 5 | If: class extends Conditional { 6 | elze: Else 7 | unwrapped: Bool = false 8 | 9 | init: func ~_if (.condition, .token) { super(condition, token) } 10 | 11 | setElse: func(=elze) 12 | getElse: func -> Else { elze } 13 | 14 | clone: func -> This { 15 | copy := new(condition ? condition clone() : null, token) 16 | body list each(|e| copy body add(e clone())) 17 | copy 18 | } 19 | 20 | accept: func (visitor: Visitor) { 21 | visitor visitIf(this) 22 | } 23 | 24 | toString: func -> String { 25 | "if (" + condition toString() + ")" + body toString() 26 | } 27 | 28 | isDeadEnd: func -> Bool { false } 29 | 30 | resolve: func(trail: Trail, res: Resolver) -> Response { 31 | if(elze != null && !unwrapped){ 32 | trail push(this) 33 | if(!trail addAfterInScope(this, elze)){ 34 | trail pop(this) 35 | res throwError(FailedUnwrapElse new(elze token, "Failed to unwrap else")) 36 | } 37 | unwrapped = true 38 | elze resolve(trail, res) 39 | trail pop(this) 40 | res wholeAgain(this, "just unwrapped else") 41 | return Response OK 42 | } 43 | 44 | super(trail, res) 45 | } 46 | 47 | } 48 | 49 | FailedUnwrapElse: class extends Error{ 50 | init: super func ~tokenMessage 51 | } 52 | -------------------------------------------------------------------------------- /source/rock/middle/Include.ooc: -------------------------------------------------------------------------------- 1 | 2 | // sdk stuff 3 | import structs/[ArrayList, List] 4 | 5 | // our stuff 6 | import Version 7 | import rock/frontend/Token 8 | import rock/middle/tinker/[Resolver, Response, Trail, Errors] 9 | 10 | IncludeMode: enum { 11 | LOCAL 12 | PATHY 13 | MACRO 14 | } 15 | 16 | Define: class { 17 | name, value: String 18 | 19 | init: func (=name, =value) {} 20 | } 21 | 22 | Include: class { 23 | 24 | token: Token 25 | path: String 26 | mode: IncludeMode 27 | verzion: VersionSpec 28 | defines := ArrayList new() 29 | 30 | init: func (=token, =path, =mode) { 31 | detectMacro() 32 | } 33 | 34 | detectMacro: func { 35 | if (path startsWith?(".")) { 36 | path = path[1..-1] 37 | mode = IncludeMode MACRO 38 | } 39 | } 40 | 41 | setVersion: func(=verzion) {} 42 | getVersion: func -> VersionSpec { verzion } 43 | 44 | addDefine: func (define: Define) { defines add(define) } 45 | getDefines: func -> List { defines } 46 | 47 | resolve: func (trail: Trail, res: Resolver) -> Response { 48 | if (verzion && !verzion isResolved()) { 49 | verzion resolve(trail, res) 50 | } 51 | Response OK 52 | } 53 | 54 | toString: func -> String { 55 | match mode { 56 | case IncludeMode LOCAL => "\"%s\"" 57 | case IncludeMode PATHY => "<%s>" 58 | } format(path) 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /source/rock/middle/Line.ooc: -------------------------------------------------------------------------------- 1 | import Node, Statement, Visitor 2 | 3 | /* 4 | Line: class extends Node { 5 | 6 | inner: Statement 7 | 8 | init: func ~line (=inner) { 9 | super(inner token) 10 | } 11 | 12 | accept: func (visitor: Visitor) { visitor visitLine(this) } 13 | 14 | replace: func (oldie, kiddo: Node) -> Bool { 15 | return match oldie { 16 | case inner => inner = kiddo; true 17 | case => false 18 | } 19 | } 20 | 21 | } 22 | */ -------------------------------------------------------------------------------- /source/rock/middle/Literal.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Expression, Node 3 | import tinker/[Resolver, Response, Trail] 4 | 5 | Literal: abstract class extends Expression { 6 | 7 | init: func (.token) { super(token) } 8 | 9 | hasSideEffects : func -> Bool { false } 10 | 11 | replace: func (oldie, kiddo: Node) -> Bool { false } 12 | 13 | isResolved: func -> Bool { 14 | getType() != null && getType() isResolved() 15 | } 16 | 17 | resolve: func (trail: Trail, res: Resolver) -> Response { 18 | 19 | if (getType() == null) { 20 | res wholeAgain(this, "null type") 21 | return Response OK 22 | } 23 | 24 | if (!getType() isResolved()) { 25 | response := getType() resolve(trail, res) 26 | if(!response ok()) return response 27 | } 28 | 29 | return Response OK 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /source/rock/middle/NullLiteral.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Expression, Node, Literal, Visitor, Type, BaseType 3 | import tinker/[Resolver, Response, Trail] 4 | 5 | NullLiteral: class extends Literal { 6 | 7 | type := static BaseType new("Pointer", nullToken) 8 | 9 | init: func ~nullLiteral (.token) { 10 | super(token) 11 | } 12 | 13 | clone: func -> This { 14 | new(token) 15 | } 16 | 17 | getType: func -> Type { type } 18 | 19 | accept: func (visitor: Visitor) { visitor visitNullLiteral(this) } 20 | 21 | toString: func -> String { "null" } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /source/rock/middle/Parenthesis.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Node, Expression, Visitor, Type 3 | import tinker/[Trail, Resolver, Response] 4 | 5 | Parenthesis: class extends Expression { 6 | 7 | inner: Expression 8 | 9 | init: func ~parenthesis (=inner, .token) { super(token) } 10 | 11 | clone: func -> This { 12 | new(inner clone(), token) 13 | } 14 | 15 | accept: func (visitor: Visitor) { 16 | visitor visitParenthesis(this) 17 | } 18 | 19 | getType: func -> Type { 20 | inner getType() 21 | } 22 | 23 | resolve: func (trail: Trail, res: Resolver) -> Response { 24 | trail push(this) 25 | response := inner resolve(trail, res) 26 | trail pop(this) 27 | 28 | return response 29 | } 30 | 31 | replace: func (oldie, kiddo: Node) -> Bool { 32 | match oldie { 33 | case inner => inner = kiddo; true 34 | case => false 35 | } 36 | } 37 | 38 | toString: func -> String { "(" + inner toString() + ")" } 39 | 40 | isResolved: func -> Bool { 41 | inner isResolved() 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /source/rock/middle/Statement.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Node 3 | 4 | Statement: abstract class extends Node { 5 | 6 | init: func ~statement (.token) { super(token) } 7 | 8 | clone: abstract func -> This 9 | 10 | } 11 | -------------------------------------------------------------------------------- /source/rock/middle/TemplateDef.ooc: -------------------------------------------------------------------------------- 1 | 2 | // sdk stuff 3 | import structs/[ArrayList, HashMap] 4 | 5 | // our stuff 6 | import Declaration, Type, Node, Visitor, VariableDecl 7 | 8 | TemplateDef: class extends Declaration { 9 | 10 | typeArgs := ArrayList new() 11 | 12 | init: func (.token) { 13 | super(token) 14 | } 15 | 16 | accept: func (visitor: Visitor) { 17 | // no-op 18 | } 19 | 20 | replace: func (oldie, kiddo: Node) -> Bool { 21 | Exception new("Can't replace in %s" format(This name)) throw() 22 | false 23 | } 24 | 25 | clone: func -> This { 26 | Exception new("Can't clone %s" format(This name)) throw() 27 | null 28 | } 29 | 30 | getType: func -> Type { 31 | Exception new("Template defs don't have types") throw() 32 | null 33 | } 34 | 35 | addTypeArg: func (typeArg: VariableDecl) -> Bool { 36 | typeArgs add(typeArg) 37 | true 38 | } 39 | 40 | toString: func -> String { 41 | sb := Buffer new() 42 | sb append("<") 43 | for ((i, typeArg) in typeArgs) { 44 | if (i > 0) sb append(", ") 45 | sb append(typeArg ? typeArg toString() : "(null)") 46 | } 47 | sb append(">") 48 | sb toString() 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /source/rock/middle/Use.ooc: -------------------------------------------------------------------------------- 1 | import UseDef 2 | 3 | import ../frontend/[Token, BuildParams] 4 | import tinker/Errors 5 | 6 | Use: class { 7 | 8 | identifier: String 9 | useDef: UseDef { get set } 10 | token: Token 11 | 12 | init: func (=identifier, params: BuildParams, =token) { 13 | useDef = UseDef parse(identifier, params) 14 | if(!useDef) { 15 | params errorHandler onError(UseNotFound new(token, identifier)) 16 | } else { 17 | useDef apply(params) 18 | } 19 | } 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /source/rock/middle/While.ooc: -------------------------------------------------------------------------------- 1 | import ../frontend/Token 2 | import Conditional, Expression, Visitor 3 | 4 | While: class extends Conditional { 5 | 6 | init: func ~_while (.condition, .token) { super(condition, token) } 7 | 8 | clone: func -> This { 9 | copy := new(condition ? condition clone() : null, token) 10 | body list each(|e| copy body add(e clone())) 11 | copy 12 | } 13 | 14 | accept: func (visitor: Visitor) { 15 | visitor visitWhile(this) 16 | } 17 | 18 | isDeadEnd: func -> Bool { false } 19 | 20 | toString: func -> String { 21 | "while (%s)" format(condition toString()) 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /source/rock/middle/tinker/Response.ooc: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Possible Response in the resolve() method. 4 | */ 5 | Response: enum { 6 | /** All good, keep going */ 7 | OK 8 | 9 | /** Hold up, trail is messed up, need to start again */ 10 | LOOP 11 | 12 | ok: func -> Bool { this == Response OK } 13 | loop: func -> Bool { this == Response LOOP } 14 | 15 | /** 16 | * @return A textual representation of this response state 17 | */ 18 | toString: func -> String { 19 | return match this { 20 | case This OK => "OK" 21 | case This LOOP => "LOOP" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /source/rock/rock.ooc: -------------------------------------------------------------------------------- 1 | use rock 2 | 3 | import structs/ArrayList 4 | import frontend/CommandLine 5 | 6 | main: func(args: ArrayList) { 7 | 8 | CommandLine new(args) 9 | 10 | } 11 | -------------------------------------------------------------------------------- /source/rock/utils/FileUtils.ooc: -------------------------------------------------------------------------------- 1 | import io/File 2 | import structs/ArrayList 3 | import text/[StringTokenizer] 4 | 5 | /** 6 | * A collection of file utilities that should have been in the 7 | * Java SDK. 8 | */ 9 | FileUtils: class { 10 | /** 11 | * Resolve redundancies, ie. ".." and "." 12 | * @param file 13 | * @return cleaned up file 14 | */ 15 | resolveRedundancies: static func(path: String) -> String { 16 | elems := ArrayList new() 17 | 18 | for (elem in path split(File separator)) { 19 | if (elem == "..") { 20 | if (!elems empty?()) { 21 | elems removeAt(elems lastIndex()) 22 | } else { 23 | elems add(elem) 24 | } 25 | } else if (elem == ".") { 26 | // do nothing 27 | } else { 28 | elems add(elem) 29 | } 30 | } 31 | 32 | mysize := elems getSize() 33 | 34 | buffer := Buffer new(path size + mysize + 1) 35 | if (path startsWith?(File separator)) { 36 | buffer append(File separator) 37 | } 38 | 39 | count := 0 40 | for (elem in elems) { 41 | buffer append(elem) 42 | count += 1 43 | if (count < mysize) { 44 | buffer append(File separator) 45 | } 46 | } 47 | return buffer toString() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.dSYM 3 | -------------------------------------------------------------------------------- /test/compiler/addons/generic-addon-realized.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | extend Cell { 4 | log: func { 5 | val println() 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/compiler/addons/generic-addon-return.ooc: -------------------------------------------------------------------------------- 1 | extend Cell { 2 | id: func -> T { 3 | return val 4 | } 5 | } 6 | 7 | describe("we should be able to return values of a generic type in generic addon", || 8 | cell := Cell new("hi") 9 | expect("hi", cell id()) 10 | ) 11 | -------------------------------------------------------------------------------- /test/compiler/addons/generic-addon-simple.ooc: -------------------------------------------------------------------------------- 1 | Foo: class { 2 | val: T 3 | 4 | init: func(=val) 5 | 6 | printClass: func { 7 | T name println() 8 | } 9 | } 10 | 11 | 12 | extend Foo { 13 | id: func -> T { 14 | val 15 | } 16 | 17 | equals?: func (other: Foo) -> Bool { 18 | val == other val 19 | } 20 | } 21 | 22 | describe("we should be able to extend a generic class generically", || 23 | foo1 := Foo new(42) 24 | foo2 := Foo new(42) 25 | 26 | expect(false, foo1 equals?(foo2)) 27 | expect(true, foo1 id() == foo2 id()) 28 | ) 29 | -------------------------------------------------------------------------------- /test/compiler/addons/generic-addon-template-realized.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | Foo: class template { 4 | magic: static func -> T { 5 | 42 6 | } 7 | } 8 | 9 | extend Foo { 10 | withMagic: static func -> Int { 11 | magic() + 1 12 | } 13 | } 14 | 15 | Foo withMagic() 16 | -------------------------------------------------------------------------------- /test/compiler/addons/generic-mixed-addon.ooc: -------------------------------------------------------------------------------- 1 | Foo: class template { 2 | val1: T 3 | val2: U 4 | 5 | init: func (=val1, =val2) 6 | } 7 | 8 | extend Foo { 9 | int_val: func -> Int { 10 | val2 toInt() 11 | } 12 | } 13 | 14 | describe("we should be able to extend a generic template class", || 15 | foo := Foo new(40, "2") 16 | expect(42, foo val1 + foo int_val()) 17 | ) 18 | -------------------------------------------------------------------------------- /test/compiler/arrays/array-as-arg.ooc: -------------------------------------------------------------------------------- 1 | 2 | takeArray: func (arr: Int[]) { 3 | expect(42, arr[0]) 4 | } 5 | 6 | describe("function call should be able to take array literal", || 7 | takeArray([42, 47, 53]) 8 | ) 9 | 10 | -------------------------------------------------------------------------------- /test/compiler/arrays/array-as-arg2.ooc: -------------------------------------------------------------------------------- 1 | 2 | takeArray: func (arr: Int[]) -> Int { 3 | expect(42, arr[0]) 4 | 1 5 | } 6 | 7 | describe("function call should be able to take array literal", || 8 | p := takeArray([42, 47, 53]) 9 | ) 10 | 11 | -------------------------------------------------------------------------------- /test/compiler/arrays/array-to-arraylist.ooc: -------------------------------------------------------------------------------- 1 | 2 | import structs/ArrayList 3 | 4 | describe("should be able to cast array to ArrayList", || 5 | keys := ["fee", "fie", "foo", "fum"] as ArrayList 6 | expect("fee", keys get(0)) 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /test/compiler/arrays/array-vdfe.ooc: -------------------------------------------------------------------------------- 1 | 2 | takeArray: func (arr: Int[]) { 3 | expect(42, arr[0]) 4 | } 5 | 6 | describe("should be able to simply declare array", || 7 | willow := [42, 47, 53] 8 | takeArray(willow) 9 | ) 10 | 11 | 12 | -------------------------------------------------------------------------------- /test/compiler/arrays/cast-to-array.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("casting to ooc array should allocate & memcpy", || 3 | carr: Int* = gc_malloc(Int size * 3) 4 | carr[0] = 1 5 | carr[1] = 2 6 | carr[2] = 3 7 | 8 | arr := carr as Int[3] 9 | expect(1, arr[0]) 10 | expect(2, arr[1]) 11 | expect(3, arr[2]) 12 | ) 13 | 14 | -------------------------------------------------------------------------------- /test/compiler/arrays/cast-to-array2.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | a := [1, 2, 3] 5 | b := a as Float[] 6 | 7 | -------------------------------------------------------------------------------- /test/compiler/arrays/return-array.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test case for https://github.com/ooc-lang/rock/issues/348 3 | 4 | f: func -> Int[] { 5 | [1, 2, 3, 4] 6 | } 7 | 8 | describe("should be able to return array", || 9 | a := f() 10 | expect(1, a[0]) 11 | expect(2, a[1]) 12 | expect(3, a[2]) 13 | expect(4, a[3]) 14 | ) 15 | -------------------------------------------------------------------------------- /test/compiler/arrays/return-array2.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test case for https://github.com/ooc-lang/rock/issues/795 3 | 4 | //! shouldfail 5 | 6 | f: func -> Int[] { 7 | [1.0, 2.0, 3.0, 4.0] 8 | } 9 | 10 | describe("should not be able to return wrong array", || 11 | a := f() 12 | expect(1, a[0]) 13 | expect(2, a[1]) 14 | expect(3, a[2]) 15 | expect(4, a[3]) 16 | ) 17 | -------------------------------------------------------------------------------- /test/compiler/classes/class-template-extend-from-non-template.ooc: -------------------------------------------------------------------------------- 1 | 2 | Foo: class template { 3 | val: T 4 | 5 | init: func (=val) 6 | } 7 | 8 | IntWrapper: class extends Foo { 9 | init: super func 10 | 11 | addOne: func -> Int { 12 | val + 1 13 | } 14 | } 15 | 16 | describe("class templates should be extendable from non-template classes when totally qualified", || 17 | i := IntWrapper new(42) 18 | expect(43, i addOne()) 19 | ) 20 | -------------------------------------------------------------------------------- /test/compiler/classes/class-template-partial-extend.ooc: -------------------------------------------------------------------------------- 1 | Foo: class template { 2 | left: T 3 | right: U 4 | 5 | init: func (=left, =right) 6 | 7 | action: func -> T { 8 | left + right 9 | } 10 | } 11 | 12 | Bar: class template extends Foo { 13 | init: func (=right) { 14 | left = 10.f 15 | } 16 | } 17 | 18 | describe("class templates should be extendable with any amount of inherited templates", || 19 | bar := Bar new(32) 20 | expect(42.f, bar action()) 21 | ) 22 | -------------------------------------------------------------------------------- /test/compiler/classes/class-template-simple.ooc: -------------------------------------------------------------------------------- 1 | 2 | Pair: class template { 3 | left: T 4 | right: V 5 | 6 | init: func (=left, =right) 7 | 8 | operator == (other: This) -> Bool { 9 | left == other left && right == other right 10 | } 11 | } 12 | 13 | 14 | describe("class templates should work", || 15 | pair1 := Pair new("hi", 0) 16 | pair2 := Pair new("world", 42) 17 | 18 | expect(false, pair1 == pair2) 19 | ) 20 | -------------------------------------------------------------------------------- /test/compiler/classes/eventually-final.ooc: -------------------------------------------------------------------------------- 1 | 2 | // cf. https://github.com/ooc-lang/rock/pull/853 3 | 4 | describe("methods can become final in subclasses (should compile)", || 5 | Second new() test() 6 | ) 7 | 8 | // suppport code 9 | 10 | First: class { 11 | init: func 12 | test: func 13 | } 14 | 15 | Second: class extends First { 16 | init: func 17 | test: final func 18 | } 19 | -------------------------------------------------------------------------------- /test/compiler/classes/final-no-longer-1.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | A: class { 4 | init: func 5 | test: func 6 | } 7 | 8 | B: class extends A { 9 | init: func 10 | test: final func 11 | } 12 | 13 | C: class extends B { 14 | init: func 15 | test: func 16 | } 17 | 18 | -------------------------------------------------------------------------------- /test/compiler/classes/final-no-longer-2.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | A: class { 4 | init: func 5 | test: func 6 | } 7 | 8 | B: class extends A { 9 | init: func 10 | test: final func 11 | } 12 | 13 | C: class extends B { 14 | init: func 15 | test: final func 16 | } 17 | 18 | -------------------------------------------------------------------------------- /test/compiler/classes/generic-template-scoring.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | Foo: class template { 3 | val: U 4 | init: func (=val) 5 | } 6 | 7 | takeAFoo: func (foo: Foo) {} 8 | 9 | foo := Foo new("hi there!") 10 | takeAFoo(foo) 11 | -------------------------------------------------------------------------------- /test/compiler/classes/load-function-once.ooc: -------------------------------------------------------------------------------- 1 | 2 | sideEffects: func -> Int { 3 | count := static 0 4 | count += 1 5 | } 6 | 7 | Base: class { 8 | count := static sideEffects() 9 | } 10 | 11 | Derived: class extends Base {} 12 | 13 | describe("class load functions should only ever be evaluated once", || 14 | expect(1, Base count) 15 | ) 16 | -------------------------------------------------------------------------------- /test/compiler/classes/parent-constructor.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | SomeException: class extends Exception { 5 | init: func (.message) { super(message) } 6 | } 7 | 8 | main: func { 9 | // throws an Exception, should err 10 | SomeException new(String, "you dun goofed") throw() 11 | } 12 | -------------------------------------------------------------------------------- /test/compiler/classes/reverse-constructor-args-on-extend.ooc: -------------------------------------------------------------------------------- 1 | 2 | A: class { 3 | init: func (callback: Func (Int), value: Int) 4 | } 5 | 6 | B: class extends A { // Wrong order of parameters 7 | init: func (value: Int, callback: Func (Int)) 8 | } 9 | -------------------------------------------------------------------------------- /test/compiler/closures/acs-reference-capture.ooc: -------------------------------------------------------------------------------- 1 | // regression test for: https://github.com/nddrylliog/rock/issues/641 2 | // "ACS capture of referenced' variables" 3 | 4 | describe("using a var's reference should capture byref", || 5 | score := -1 6 | call(|| setIntegerTo(score&, 42)) 7 | expect(42, score) 8 | ) 9 | 10 | // support code 11 | 12 | call: func (f: Func) { f() } 13 | 14 | setIntegerTo: func (dst: Int@, value: Int) { 15 | dst = value 16 | } 17 | 18 | -------------------------------------------------------------------------------- /test/compiler/closures/nest-up-and-away.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/907 3 | 4 | finalValue: Int = 42 5 | 6 | a := func { 7 | c: Int = 0 8 | b := func { 9 | c: Int = 1 10 | d := func { 11 | c: Int = 2 12 | e := func { 13 | finalValue = c 14 | } 15 | e() 16 | } 17 | d() 18 | } 19 | b() 20 | } 21 | 22 | describe("rock should generate valid code with any number of nested closures", || 23 | a() 24 | expect(2, finalValue) 25 | ) 26 | 27 | -------------------------------------------------------------------------------- /test/compiler/closures/nested-assignment.ooc: -------------------------------------------------------------------------------- 1 | 2 | done := false 3 | 4 | main: func { 5 | myFunc: Func (Int) 6 | myFunc_imp := func (i: Int) { done = true } 7 | myFunc = myFunc_imp 8 | 9 | myFunc(3) 10 | expect(true, done) 11 | "Pass" println() 12 | } 13 | -------------------------------------------------------------------------------- /test/compiler/closures/nested-closures.ooc: -------------------------------------------------------------------------------- 1 | 2 | // cf. https://github.com/ooc-lang/rock/issues/882 3 | 4 | describe("nested closures should be able to modify outer variable by ref", || 5 | g := (1, 0) as Tuple 6 | please(|| 7 | g = (2, 0) as Tuple 8 | please(|| 9 | g = (3, 0) as Tuple 10 | ) 11 | ) 12 | expect(g a, 3) 13 | ) 14 | 15 | describe("nested closures should not capture outer var by ref by default", || 16 | g := (1, 0) as Tuple 17 | please(|| 18 | g a = 2 19 | ) 20 | expect(g a, 1) 21 | ) 22 | 23 | describe("nested closures should capture outer var by ref when marked", || 24 | g := (1, 0) as Tuple 25 | please(|| 26 | please(|| 27 | g = g 28 | g a = 2 29 | ) 30 | ) 31 | expect(g a, 2) 32 | ) 33 | 34 | // support code 35 | 36 | Tuple: cover { 37 | a, b: Int 38 | } 39 | 40 | please: func (f: Func) { f() } 41 | -------------------------------------------------------------------------------- /test/compiler/closures/non-acs-in-closure.ooc: -------------------------------------------------------------------------------- 1 | 2 | // regression test for: https://github.com/ooc-lang/rock/issues/885 3 | 4 | describe("should call static function from closure", || 5 | f := func { 6 | // woof! 7 | } 8 | f() 9 | ) 10 | 11 | -------------------------------------------------------------------------------- /test/compiler/control/foreach-index.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("foreach should allow storing index in variable via tuple", || 3 | a := "hello dolly" 4 | b := Buffer new() 5 | 6 | for ((i, c) in a) { 7 | expect(c, a[i]) 8 | 9 | if (c == 'l') continue 10 | if (c == ' ') break 11 | 12 | b append(c) 13 | } 14 | result := b toString() 15 | 16 | expect("heo", result) 17 | ) 18 | -------------------------------------------------------------------------------- /test/compiler/control/foreach-range-generated.ooc: -------------------------------------------------------------------------------- 1 | counter := 0 2 | 3 | f: func -> Range { 4 | counter += 1 // Side effects! 5 | 6 | 10 .. 15 7 | } 8 | 9 | describe("foreach should iterate through any range expression, not just literals", || 10 | 11 | for ((j, i) in f()) { 12 | expect(j + 10, i) 13 | } 14 | 15 | expect(counter, 1) 16 | ) 17 | -------------------------------------------------------------------------------- /test/compiler/control/foreach-range-index.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("foreach should iterate through range with index", || 3 | iterations := 0 4 | 5 | for ((i, x) in 0..10) { 6 | iterations += 1 7 | expect(x, i) 8 | } 9 | 10 | expect(10, iterations) 11 | ) 12 | -------------------------------------------------------------------------------- /test/compiler/control/foreach-range.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("foreach should iterate through range", || 3 | j := 0 4 | total := 0 5 | for (i in 0..10) { 6 | total += 1 7 | expect(j, i) 8 | j += 1 9 | } 10 | 11 | expect(10, total) 12 | ) 13 | -------------------------------------------------------------------------------- /test/compiler/control/foreach.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("foreach should support iterating through String (Iterable)", || 3 | a := "hello" 4 | b := Buffer new() 5 | 6 | for (c in a) { 7 | b append(c) 8 | } 9 | result := b toString() 10 | 11 | expect(a, result) 12 | ) 13 | -------------------------------------------------------------------------------- /test/compiler/control/gencall-inbetween.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("generic call should not happen between if and else", || 3 | cell := Cell new("pass") 4 | 5 | if (false) { 6 | // Muffin 7 | } else { 8 | (a, b) := Duplicator dup(cell get()) 9 | expect("pass", a) 10 | expect(a, b) 11 | } 12 | ) 13 | 14 | // support code 15 | 16 | Duplicator: class { 17 | dup: static func (a: String) -> (String, String) { 18 | (a, a) 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/compiler/control/invalid-match-type-inference.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | // There's no common ancestor between String and Int, so 5 | // match can't infer its type. 6 | f: func -> Int { 7 | if(true) { 8 | match { 9 | case true => "Hi!" 10 | case => 42 11 | } 12 | } else { 13 | 0 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-from-underlying-access.ooc: -------------------------------------------------------------------------------- 1 | Foo: cover { 2 | bar: Int 3 | } 4 | 5 | Bar: cover from Foo extends Foo 6 | 7 | describe("rock should generate correct code for accesses of members of underlying covers", || 8 | f: Bar 9 | f bar = 2 10 | 11 | expect(f bar, 2) 12 | ) 13 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-template-cross-reference.ooc: -------------------------------------------------------------------------------- 1 | 2 | Foo: cover template { 3 | val: T 4 | 5 | init: func@ (=val) 6 | 7 | bar: func@ -> Bar { 8 | Bar new(this&) 9 | } 10 | } 11 | 12 | Bar: cover template { 13 | ref: Foo* 14 | 15 | init: func@ (=ref) 16 | } 17 | 18 | describe("we should be able to create cross-referencing cover templates", || 19 | foo := Foo new(42) 20 | 21 | expect(foo&, foo bar() ref) 22 | ) 23 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-template-unused-segfault.ooc: -------------------------------------------------------------------------------- 1 | Foo: cover template { 2 | init: func@ 3 | } 4 | 5 | describe("uninstantiated cover templates should not cause rock to segfault", ||) 6 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-template-vector.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("a fairly complex cover template class", || 3 | vf := Vec2 new(1.0, 1.0) 4 | vf add!(1.0, 2.0) 5 | 6 | expect(2.0, vf x) 7 | expect(3.0, vf y) 8 | 9 | vi := Vec2 new(3, 4) 10 | vi = vi add(4, 4) 11 | 12 | expect(7, vi x) 13 | expect(8, vi y) 14 | ) 15 | 16 | // support code 17 | 18 | Vec2: cover template { 19 | x, y: T 20 | 21 | init: func@ (=x, =y) 22 | 23 | clone: func -> This { 24 | new(x, y) 25 | } 26 | 27 | add!: func@ (.x, .y) { 28 | this x += x 29 | this y += y 30 | } 31 | 32 | add: func (.x, .y) -> This { 33 | c := clone() 34 | c add!(x, y) 35 | c 36 | } 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-templates-generic-function.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/626 3 | 4 | result := 0 5 | 6 | describe("", || 7 | foo := Foo new(Bar clear) 8 | foo doThing() 9 | expect(42, result) 10 | ) 11 | 12 | Foo: cover template { 13 | fn: Func (T) 14 | 15 | init: func@ (=fn) 16 | 17 | doThing: func { 18 | fn(42) 19 | } 20 | } 21 | 22 | Bar: class { 23 | clear: static func (a:T) { 24 | match a { 25 | case i: Int => 26 | result = i 27 | } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-templates-generic-function2.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | // Test for https://github.com/ooc-lang/rock/issues/626 5 | 6 | result := 0 7 | 8 | describe("", || 9 | foo := Foo new(Bar clear) 10 | foo doThing() 11 | expect(42, result) 12 | ) 13 | 14 | Foo: cover template { 15 | fn: Func (T) 16 | 17 | init: func@ (=fn) 18 | 19 | doThing: func { 20 | fn(42) 21 | } 22 | } 23 | 24 | Bar: class { 25 | clear: static func (i: Int) { 26 | result = i 27 | } 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-templates-generic-function3.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | // Test for https://github.com/ooc-lang/rock/issues/626 5 | 6 | result := 0 7 | 8 | describe("", || 9 | foo := Foo new(Bar clear) 10 | foo doThing() 11 | expect(42, result) 12 | ) 13 | 14 | Foo: cover template { 15 | fn: Func (T) 16 | 17 | init: func@ (=fn) 18 | 19 | doThing: func { 20 | fn(42) 21 | } 22 | } 23 | 24 | Bar: class { 25 | clear: func (a:T) { 26 | match a { 27 | case i: Int => 28 | result = i 29 | } 30 | } 31 | } 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-templates-string-interpolation.ooc: -------------------------------------------------------------------------------- 1 | 2 | // test for https://github.com/ooc-lang/rock/issues/886 3 | 4 | formatInt: func (i: Int) -> String { 5 | "~#{i}" 6 | } 7 | 8 | Something: cover template { 9 | 10 | init: func 11 | 12 | format: func (t: T) -> String { 13 | "+#{t}" 14 | } 15 | 16 | } 17 | 18 | describe("string interpolation in cover templates", || 19 | expect("~42", formatInt(42)) 20 | expect("+42", Something new() format(42)) 21 | expect("+hi", Something new() format("hi")) 22 | ) 23 | 24 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-templates-string-interpolation2.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | Vec2: cover { 5 | x, y: Float 6 | } 7 | 8 | Something: cover template { 9 | 10 | init: func 11 | 12 | format: func (t: T) -> String { 13 | "+#{t}" 14 | } 15 | 16 | } 17 | 18 | Something new() format((1.0f, 2.0f) as Vec2) 19 | 20 | -------------------------------------------------------------------------------- /test/compiler/covers/cover-templates2.ooc: -------------------------------------------------------------------------------- 1 | 2 | // this test triggers a particular bug in old versions of rock 3 | // where resolve orders is so that things don't get resolved properly. 4 | // see https://github.com/ooc-lang/rock/issues/887 5 | 6 | assignDone := false 7 | pleaseDone := false 8 | 9 | Something: cover template { 10 | 11 | t: T 12 | 13 | init: func@ (=t) 14 | 15 | blah: func -> T { 16 | t2: T 17 | 18 | assign := func (t3: T) { 19 | assignDone = true 20 | t2 = t3 21 | } 22 | 23 | please(|t4| 24 | assign(t4) 25 | ) 26 | 27 | t2 28 | } 29 | 30 | please: func (f: Func(T)) { 31 | pleaseDone = true 32 | f(t) 33 | } 34 | 35 | } 36 | 37 | describe("somewhat complicated cover template test", || 38 | s := Something new(42) 39 | v := s blah() 40 | expect(42, v) 41 | ) 42 | 43 | -------------------------------------------------------------------------------- /test/compiler/covers/not-object-in-match.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | printName: func (data: Object) { 5 | data class name println() 6 | } 7 | 8 | printName(2) 9 | 10 | -------------------------------------------------------------------------------- /test/compiler/covers/pointer-comparison.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/783 3 | 4 | describe("it should be legal to compare the address of structs", || 5 | s := (1, 5) as S 6 | a := s& 7 | b := s& 8 | 9 | expect(b, a) 10 | ) 11 | 12 | // Support code 13 | 14 | S: cover { 15 | x, y: Int 16 | } 17 | 18 | -------------------------------------------------------------------------------- /test/compiler/covers/template-invalid-assignment.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | Vec2: cover template { 4 | x, y: T 5 | 6 | init: func@ (=x, =y) 7 | } 8 | 9 | describe("should not be able to assign incompatible template instances", || 10 | vf := Vec2 new(1.0, 1.0) 11 | vi := Vec2 new(1, 1) 12 | 13 | vf = vi 14 | ) 15 | -------------------------------------------------------------------------------- /test/compiler/covers/template-valid-assignment.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("should be able to assign cover templates of the same type", || 3 | vf1 := Vec2 new(1.0, 1.0) 4 | vf1 = Vec2 new(1.0, 1.0) 5 | 6 | expect(vf1 x, vf1 y) 7 | ) 8 | 9 | Vec2: cover template { 10 | x, y: T 11 | 12 | init: func@ (=x, =y) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /test/compiler/enums/versioned-enum.ooc: -------------------------------------------------------------------------------- 1 | version (!gc) { 2 | Foo: enum { 3 | test = UNDEFINED_C_CONST 4 | } 5 | } -------------------------------------------------------------------------------- /test/compiler/functions/call-combo1.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/pull/901 3 | 4 | describe("bar test()(1) should be recognized properly", || 5 | bar := Foo new() 6 | 7 | a := bar test() 8 | a(1) 9 | 10 | bar test()(1) 11 | ) 12 | 13 | // Support code 14 | 15 | Foo: class { 16 | v: Int 17 | isOdd: Bool { 18 | get { v % 2 == 1 } 19 | } 20 | 21 | isEven ::= v %2 == 0 22 | 23 | init: func 24 | 25 | test: func -> Func (Int) { 26 | return func (a: Int) { a toString() println()} 27 | } 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/compiler/functions/call-combo2.ooc: -------------------------------------------------------------------------------- 1 | 2 | //!shouldfail 3 | 4 | // Test for https://github.com/ooc-lang/rock/pull/901 5 | 6 | describe("bar test()() should be a compile error (args mismatch)", || 7 | bar := Foo new() 8 | bar test()() 9 | ) 10 | 11 | // Support code 12 | 13 | Foo: class { 14 | v: Int 15 | isOdd: Bool { 16 | get { v % 2 == 1 } 17 | } 18 | 19 | isEven ::= v %2 == 0 20 | 21 | init: func 22 | 23 | test: func {} 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /test/compiler/functions/generic-return.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("should return proper type when explicitly specifying generic typeArg", || 3 | v := blooey(Int) 4 | expect(42, v) 5 | ) 6 | 7 | // support code 8 | 9 | blooey: func (T: Class) -> T { 10 | match T { 11 | case Int => 42 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /test/compiler/functions/generic-return2.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("should be able to return Int value through two levels of generic functions", || 3 | v := kablooey(Int) 4 | expect(42, v) 5 | ) 6 | 7 | // support code 8 | 9 | blooey: func (T: Class) -> T { 10 | match T { 11 | case Int => 42 12 | } 13 | } 14 | 15 | kablooey: func (T: Class) -> T { 16 | blooey(T) 17 | } 18 | 19 | -------------------------------------------------------------------------------- /test/compiler/functions/inference-precision-loss.ooc: -------------------------------------------------------------------------------- 1 | 2 | kalamazoo: func ~Int (a, b: Int) -> String { "Int" } 3 | kalamazoo: func ~Double (a, b: Double) -> String { "Double" } 4 | 5 | check: func (result, signature, expected: String) { 6 | if (result != expected) { 7 | "Fail! expected (#{signature}) to call ~#{expected}, but got ~#{result} instead." println() 8 | exit(1) 9 | } 10 | } 11 | 12 | main: func { 13 | check(kalamazoo(1.0, 1.0), "Double, Double", "Double") 14 | check(kalamazoo(1.0, 1), "Double, Int", "Double") 15 | check(kalamazoo(1, 1.0), "Int, Double", "Double") 16 | check(kalamazoo(1, 1), "Int, Int", "Int") 17 | 18 | "Pass" println() 19 | } 20 | 21 | -------------------------------------------------------------------------------- /test/compiler/functions/invalid-abstract-func-addon.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | Foo: abstract class {} 4 | 5 | extend Foo { 6 | doThings: abstract func(with: Int) 7 | } 8 | -------------------------------------------------------------------------------- /test/compiler/functions/invalid-abstract-outside-class.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | f: abstract func(i: Int) -> Int { 4 | i + 1 5 | } -------------------------------------------------------------------------------- /test/compiler/functions/invalid-return1.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | voidy: func { 4 | return 1 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/compiler/functions/invalid-return2.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | valuey: func -> Int { 4 | return 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/compiler/functions/invalid-return3.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | valuey: func -> Int { 4 | return "yeow" 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/compiler/functions/malformed-function.ooc: -------------------------------------------------------------------------------- 1 | //!shouldfail 2 | 3 | Foo: class { 4 | bar: func ~suffix func (test: Int) 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/compiler/functions/multi-init.ooc: -------------------------------------------------------------------------------- 1 | 2 | intDone := false 3 | strDone := false 4 | 5 | describe("Should call right constructor based on suffix", || 6 | Dog new(42) 7 | Dog new("43") 8 | 9 | expect(true, intDone) 10 | expect(true, strDone) 11 | ) 12 | 13 | // support code 14 | 15 | Dog: class { 16 | 17 | init: func ~int (a: Int) { 18 | intDone = true 19 | } 20 | 21 | init: func ~str (a: String) { 22 | strDone = true 23 | } 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/compiler/functions/redefinition-in-extend-suffix.ooc: -------------------------------------------------------------------------------- 1 | 2 | import structs/ArrayList 3 | 4 | describe("redefinition in extend with suffix should work", || 5 | a := ArrayList new() 6 | expect(false, a exists?()) 7 | 8 | b := ArrayList new() 9 | expect(true, b exists?("hello")) 10 | ) 11 | 12 | // support code 13 | 14 | extend ArrayList { 15 | exists?: func -> Bool { 16 | return false 17 | } 18 | } 19 | 20 | extend ArrayList { 21 | exists?: func ~string (i: String) -> Bool{ 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /test/compiler/functions/redefinition-in-extend-vs-base.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | base: class { 4 | exists?: func -> Bool { return false } 5 | } 6 | 7 | extend base { 8 | exists?: func -> Bool { return true } 9 | } 10 | -------------------------------------------------------------------------------- /test/compiler/functions/redefinition-in-extend.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | import structs/ArrayList 4 | 5 | extend ArrayList { 6 | exists?: func -> Bool{ 7 | return false 8 | } 9 | } 10 | 11 | extend ArrayList { 12 | exists?: func (i: String) -> Bool{ 13 | return true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/compiler/functions/segfault-on-build.ooc: -------------------------------------------------------------------------------- 1 | 2 | 3 | //! shouldfail 4 | 5 | // Test for https://github.com/ooc-lang/rock/issues/811 6 | 7 | Foo: class { 8 | done: Bool { get { 9 | this lock(f) 10 | } } 11 | } 12 | -------------------------------------------------------------------------------- /test/compiler/functions/static-func-addon.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("should allow statis funcs in addon", || 3 | bar := Foo bar() 4 | expect(42, bar x) 5 | ) 6 | 7 | // support code 8 | 9 | Foo: class { 10 | x: Int 11 | 12 | init: func(=x) 13 | } 14 | 15 | extend Foo { 16 | bar: static func -> This { 17 | Foo new(42) 18 | } 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /test/compiler/functions/unqualified-static-first-class-call.ooc: -------------------------------------------------------------------------------- 1 | 2 | // regression test for: https://github.com/ooc-lang/rock/issues/635 3 | // "Can't call static first-class functions without the class name." 4 | 5 | // Don't use sam-assert, otherwise we hit #885 6 | main: func { 7 | Dog onBark = func { 8 | "woof" println() 9 | } 10 | Dog bark() 11 | } 12 | 13 | // Support code 14 | 15 | Dog: class { 16 | onBark: static Func 17 | bark: static func { 18 | // onBark should resolve to Dog.onBark static var Func 19 | onBark() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/compiler/functions/valid-return.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("should do implicit cast when returning", || 3 | v := valuey() 4 | expect(3, v) 5 | ) 6 | 7 | valuey: func -> Int { 8 | return 3.14 9 | } 10 | 11 | -------------------------------------------------------------------------------- /test/compiler/functions/var-redef1.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | foo: func (i: Int) { 4 | i := 4 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/compiler/functions/var-redef2.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | foo: func (i: Int) { 4 | (a, i) := ("Hello", 4) 5 | } 6 | -------------------------------------------------------------------------------- /test/compiler/functions/var-redef3.ooc: -------------------------------------------------------------------------------- 1 | 2 | foo: func (i: Int) { 3 | for (j in 0..4) { 4 | i := 4 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /test/compiler/generics/cannot-reassign-typeargs.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | c := Cell new(42) 4 | c T = String 5 | -------------------------------------------------------------------------------- /test/compiler/generics/casting-to-generic.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | // Test for https://github.com/ooc-lang/rock/issues/891 5 | 6 | Peeker: class { 7 | inner: Object 8 | init: func (=inner) 9 | peek: func (T: Class) -> T { 10 | inner as T 11 | } 12 | } 13 | 14 | describe("casting to generic is forbidden", || 15 | p := Peeker new("hi!") 16 | expect("hi!", p peek(String)) 17 | ) 18 | -------------------------------------------------------------------------------- /test/compiler/generics/function-typearg-infer-from-closure-return-type.ooc: -------------------------------------------------------------------------------- 1 | Foo: class { init: func } 2 | 3 | f: func (foo: Func -> Foo) { 4 | Oh name println() 5 | My name println() 6 | God name println() 7 | } 8 | 9 | describe("Typeargs should be inferred from closure argument return type", || 10 | f(|| Foo new()) 11 | ) 12 | -------------------------------------------------------------------------------- /test/compiler/generics/function-typearg-infer-from-nested-generic-argument.ooc: -------------------------------------------------------------------------------- 1 | 2 | // regression test for https://github.com/nddrylliog/rock/issues/639 3 | Bag: class { 4 | j: J 5 | k: K 6 | l: L 7 | init: func (=j, =k, =l) 8 | } 9 | 10 | peekaboo: func (arg: Bag, arg2: Bag) { 11 | "A = %s" printfln(A name) 12 | "B = %s" printfln(B name) 13 | "C = %s" printfln(C name) 14 | "D = %s" printfln(D name) 15 | "E = %s" printfln(E name) 16 | "F = %s" printfln(F name) 17 | } 18 | 19 | main: func { 20 | peekaboo(Bag new(3.14, 42, "Huhu"), Bag new(3.14, 42, "Huhu")) 21 | } 22 | -------------------------------------------------------------------------------- /test/compiler/generics/generic-member.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/889 3 | 4 | describe("accessing generic member should not require a cast", || 5 | g := Gift new("hi") 6 | g tuvalu println() 7 | ) 8 | 9 | Gift: class { 10 | tuvalu: T 11 | init: func (=tuvalu) 12 | } 13 | -------------------------------------------------------------------------------- /test/compiler/generics/generic-member2.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/889 3 | 4 | describe("should be able to assign, plus-assign, access generic member", || 5 | g := Gift new(42) 6 | 7 | "#{g tuvalu}" println() 8 | expect(42, g tuvalu) 9 | 10 | g tuvalu = 10 11 | expect(10, g tuvalu) 12 | 13 | i: Int 14 | i = g tuvalu 15 | expect(10, i) 16 | 17 | g tuvalu += 8 18 | expect(18, g tuvalu) 19 | ) 20 | 21 | Gift: class { 22 | tuvalu: T 23 | init: func (=tuvalu) 24 | } 25 | 26 | -------------------------------------------------------------------------------- /test/compiler/generics/generic-member3.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/889 3 | 4 | import structs/ArrayList 5 | 6 | describe("should be able access member with its own typeargs", || 7 | g := Gift new("hi") 8 | g list get(0) println() 9 | ) 10 | 11 | Gift: class { 12 | list: ArrayList 13 | init: func (t: T) { 14 | list = ArrayList new() 15 | list add(t) 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /test/compiler/generics/infer-from-type-hierarchy.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Not linked to any issue in particular, just a regression test 3 | // for when we refactor the generics code again. 4 | 5 | import structs/Stack 6 | 7 | done := false 8 | 9 | describe("type args should be inferred from type hierarchy", || 10 | t := Trail new() 11 | 12 | for (tuvalu in t backward()) { 13 | tuvalu doStuff() 14 | } 15 | 16 | expect(true, done) 17 | ) 18 | 19 | // Support code 20 | 21 | Node: class { 22 | init: func 23 | doStuff: func { 24 | done = true 25 | } 26 | } 27 | 28 | Trail: class extends Stack { 29 | init: func { 30 | super() 31 | push(Node new()) 32 | } 33 | } 34 | 35 | getType: func (t: T) -> String { 36 | T name 37 | } 38 | 39 | -------------------------------------------------------------------------------- /test/compiler/generics/iterate-hashmap-keys.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/361 3 | 4 | import structs/HashMap 5 | 6 | describe("should be able to iterate over hashmap keys", || 7 | hm := HashMap new() 8 | hm put("foo", "bar") 9 | 10 | for (key in hm keys) { 11 | expect("foo", key) 12 | } 13 | ) 14 | 15 | -------------------------------------------------------------------------------- /test/compiler/generics/match-generic-types.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/802 3 | 4 | getType: func (t: T) -> String { 5 | match t { 6 | case i: Int => 7 | "integer" 8 | case c: Cell => 9 | "a cell!" 10 | case => 11 | "not sure.." 12 | } 13 | } 14 | 15 | describe("should be able to match a generic type without writing its typeargs", || 16 | expect("integer", getType(42)) 17 | expect("a cell!", getType(Cell new(42))) 18 | ) 19 | 20 | -------------------------------------------------------------------------------- /test/compiler/generics/pass-invalid-generic-arg.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | import structs/ArrayList 5 | 6 | // Test case for https://github.com/ooc-lang/rock/issues/842 7 | 8 | describe("should refuse invalid generic assignment", || 9 | data: ArrayList> 10 | data = ArrayList new() 11 | data add(ArrayList new) 12 | data[0] add(1) 13 | ) 14 | 15 | -------------------------------------------------------------------------------- /test/compiler/generics/pointer-size.ooc: -------------------------------------------------------------------------------- 1 | 2 | check: func (t: T) { 3 | if (T size != Pointer size) { 4 | "Fail! T size should be #{Pointer size}, is #{T size}" println() 5 | exit(1) 6 | } 7 | } 8 | 9 | main: func { 10 | a: Int* 11 | check(a) 12 | 13 | b: UInt64* 14 | check(b) 15 | 16 | c: Char* 17 | check(c) 18 | 19 | "Pass" println() 20 | } 21 | -------------------------------------------------------------------------------- /test/compiler/generics/reconcile-1.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/825 3 | 4 | Foo: class { init: func } 5 | Bar: class extends Foo { init: super func } 6 | 7 | falafel: func (a, b: Tuvalu) -> String { 8 | Tuvalu name 9 | } 10 | 11 | describe("should infer to common root, not first generic arg", || 12 | type := falafel(Bar new(), Foo new()) 13 | expect("Foo", type) 14 | ) 15 | 16 | -------------------------------------------------------------------------------- /test/compiler/generics/reconcile-not-1.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | // Test for https://github.com/ooc-lang/rock/issues/825 5 | 6 | Foo: class { init: func } 7 | 8 | falafel: func (a, b: Tuvalu) -> String { 9 | Tuvalu name 10 | } 11 | 12 | describe("should refuse to reconcile irreconcilable types", || 13 | type := falafel(42, Foo new()) 14 | expect("Foo", type) 15 | ) 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/compiler/generics/typewidth.ooc: -------------------------------------------------------------------------------- 1 | 2 | IntPointer: cover from Int* 3 | 4 | main: func { 5 | a: Int* = [1, 2, 3] 6 | check(a, "Pointer") 7 | check(func {}, "Pointer") 8 | check("Hello", "String") 9 | "Pass" println() 10 | } 11 | 12 | check: func (t: T, name: String) { 13 | match (T name) { 14 | case name => 15 | // good 16 | case => 17 | "Fail, expected: " print() 18 | name print() 19 | ", got: " print() 20 | T name println() 21 | exit(1) 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /test/compiler/generics/unwrap-with-return-args.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/890 3 | 4 | Ditto: class { 5 | s: String 6 | init: func (=s) 7 | 8 | operator + (other: This) -> This { 9 | new(s + other s) 10 | } 11 | } 12 | 13 | Container: class { 14 | ditto := Ditto new("john") 15 | init: func 16 | } 17 | 18 | Peeker: class { 19 | inner: Object 20 | init: func (=inner) 21 | peek: func (T: Class) -> T { inner } 22 | } 23 | 24 | describe("should unwrap += correctly even with returnArgs", || 25 | c := Container new() 26 | p := Peeker new(c) 27 | 28 | // forced to unwrap, only has '+' operator 29 | p peek(Container) ditto += Ditto new(" doe") 30 | 31 | expect("john doe", c ditto s) 32 | ) 33 | 34 | -------------------------------------------------------------------------------- /test/compiler/generics/use-owner-not-this.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/346 3 | 4 | import structs/HashBag 5 | 6 | Pair: class { 7 | kik: Kakhi 8 | v: V 9 | 10 | init: func (=kik, =v) {} 11 | } 12 | 13 | index := 0 14 | 15 | gprint: func (t: Tina) { 16 | r := match t { 17 | case i: Int => "#{i}" 18 | case s: String => "#{s}" 19 | case => "nope" 20 | } 21 | match index { 22 | case 0 => expect("Hello", r) 23 | case 1 => expect("World!", r) 24 | case 2 => expect("leet", r) 25 | case 3 => expect("1337", r) 26 | } 27 | index += 1 28 | } 29 | 30 | hashbag: func (args: ...) { 31 | args each(|arg| 32 | pair := arg as Pair 33 | gprint(pair kik) 34 | gprint(pair v) 35 | ) 36 | } 37 | 38 | describe("should refer to typeArg from owner, not 'this'", || 39 | hashbag(Pair new("Hello", "World!"), Pair new("leet", 1337)) 40 | ) 41 | 42 | -------------------------------------------------------------------------------- /test/compiler/generics/use-owner-not-this2.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/346 3 | 4 | import structs/HashBag 5 | 6 | Pair: class { 7 | kik: Kakhi 8 | v: V 9 | 10 | init: func (=kik, =v) {} 11 | } 12 | 13 | index := 0 14 | 15 | gprint: func (t: Tina) { 16 | r := match t { 17 | case i: Int => "#{i}" 18 | case s: String => "#{s}" 19 | case => "nope" 20 | } 21 | match index { 22 | case 0 => expect("Hello", r) 23 | case 1 => expect("World!", r) 24 | case 2 => expect("leet", r) 25 | case 3 => expect("1337", r) 26 | } 27 | index += 1 28 | } 29 | 30 | operator => (k: K, v: V) -> Pair { Pair new(k, v) } 31 | 32 | hashbag: func (args: ...) { 33 | args each(|arg| 34 | pair := arg as Pair 35 | gprint(pair kik) 36 | gprint(pair v) 37 | ) 38 | } 39 | 40 | describe("should refer to typeArg from owner, not 'this'", || 41 | hashbag("Hello" => "World!", "leet" => 1337) 42 | ) 43 | 44 | 45 | -------------------------------------------------------------------------------- /test/compiler/interfaces/interface-provided-function.ooc: -------------------------------------------------------------------------------- 1 | Printable: interface { 2 | toString: func -> String 3 | 4 | print: func { 5 | toString() println() 6 | } 7 | } 8 | 9 | Foo: class implements Printable { 10 | count := static 0 11 | 12 | init: func { 13 | count += 1 14 | } 15 | 16 | toString: func -> String { "foo##{count}" } 17 | } 18 | 19 | describe("interfaces should be able to provide default implementations without rock crashing", || 20 | expect("foo#1", Foo new() toString()) 21 | ) 22 | -------------------------------------------------------------------------------- /test/compiler/interfaces/invalid-function-implementation.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | Foo: interface { 4 | bar: func -> String 5 | } 6 | 7 | Bar: class implements Foo { 8 | bar: func -> Int { 9 | 0 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/compiler/interfaces/multiple-interface-implementation.ooc: -------------------------------------------------------------------------------- 1 | Readable: interface { 2 | read: func -> String 3 | } 4 | 5 | Writeable: interface { 6 | write: func(what: String) 7 | } 8 | 9 | Foo: class implements Readable, Writeable { 10 | _internal: String 11 | 12 | init: func 13 | 14 | read: func -> String { _internal } 15 | write: func(what: String) { _internal = what } 16 | } 17 | 18 | main: func { 19 | foo := Foo new() 20 | 21 | foo write("test") 22 | if(foo read() != "test") { 23 | "Fail!" println() 24 | exit(1) 25 | } 26 | 27 | "Pass" println() 28 | exit(0) 29 | } 30 | -------------------------------------------------------------------------------- /test/compiler/interfaces/simple-function-implementation.ooc: -------------------------------------------------------------------------------- 1 | Foo: interface { 2 | bar: func -> String 3 | } 4 | 5 | Bar: class implements Foo { 6 | x: String 7 | 8 | init: func(=x) 9 | 10 | bar: func -> String { 11 | x 12 | } 13 | } 14 | 15 | main: func { 16 | bar := Bar new("hi!") 17 | 18 | if(bar bar() != "hi!") { 19 | "Fail!" println() 20 | exit(1) 21 | } 22 | 23 | "Pass" println() 24 | exit(0) 25 | } 26 | -------------------------------------------------------------------------------- /test/compiler/literals/array-literal-in-class.ooc: -------------------------------------------------------------------------------- 1 | Foo: class{ 2 | test := [1, 2, 3] 3 | init: func 4 | } 5 | 6 | Bar: class{ 7 | test := static const [1, 2, 3] 8 | init: func 9 | } 10 | 11 | describe("ArrayLiteral should be correctly unwrapped",|| 12 | foo := Foo new() 13 | assert(foo test[0] == 1) 14 | assert(foo test[1] == 2) 15 | assert(foo test[2] == 3) 16 | assert(Bar test[0] == 1) 17 | assert(Bar test[1] == 2) 18 | assert(Bar test[2] == 3) 19 | ) 20 | -------------------------------------------------------------------------------- /test/compiler/literals/fp-literal-scientific.ooc: -------------------------------------------------------------------------------- 1 | 2 | check: func (t: T, ref: Class) { 3 | if (T != ref) { 4 | "Fail! expected #{ref name}, got #{T name}" println() 5 | exit(1) 6 | } 7 | } 8 | 9 | checkDouble: func (a, b: Double) { 10 | if (a != b) { 11 | "Fail! Expected a == b, but got a = %f, b = %f" printfln(a, b) 12 | exit(1) 13 | } 14 | } 15 | 16 | checkFloat: func (a, b: Float) { 17 | if (a != b) { 18 | "Fail! Expected a == b, but got a = %f, b = %f" printfln(a, b) 19 | exit(1) 20 | } 21 | } 22 | 23 | main: func { 24 | check(3.14e+0, Double) 25 | check(3.14E+3, Double) 26 | check(314.0E-2, Double) 27 | check(3.14e+0f, Float) 28 | check(3.14E+3f, Float) 29 | check(314.0E-2f, Float) 30 | 31 | checkDouble(3.14e+0, 3.14) 32 | checkDouble(3.14E+3, 3140.0) 33 | checkDouble(314.0E-2, 3.14) 34 | checkFloat(3.14e+0f, 3.14f) 35 | checkFloat(3.14E+3f, 3140.0f) 36 | checkFloat(314.0E-2f, 3.14f) 37 | 38 | "Pass" println() 39 | } 40 | 41 | -------------------------------------------------------------------------------- /test/compiler/literals/fp-literal-suffixes.ooc: -------------------------------------------------------------------------------- 1 | 2 | check: func (t: T, ref: Class) { 3 | if (T != ref) { 4 | "Fail! expected #{ref name}, got #{T name}" println() 5 | exit(1) 6 | } 7 | } 8 | 9 | main: func { 10 | check(3.5, Double) 11 | check(3.5f, Float) 12 | check(3.5F, Float) 13 | check(3.5l, LDouble) 14 | check(3.5L, LDouble) 15 | 16 | "Pass" println() 17 | } 18 | 19 | -------------------------------------------------------------------------------- /test/compiler/literals/int-literal-suffixes.ooc: -------------------------------------------------------------------------------- 1 | 2 | check: func (t: T, ref: Class) { 3 | if (T != ref) { 4 | "Fail! expected #{ref name}, got #{T name}" println() 5 | exit(1) 6 | } 7 | } 8 | 9 | checkValue: func (val, ref: UInt) { 10 | if (val != ref) { 11 | "Fail! expected #{ref}, got #{val}" println() 12 | exit(1) 13 | } 14 | } 15 | 16 | main: func { 17 | check(42, Int) 18 | check(42u, UInt) 19 | check(42U, UInt) 20 | check(42l, Long) 21 | check(42L, Long) 22 | check(42ll, LLong) 23 | check(42LL, LLong) 24 | check(42ull, ULLong) 25 | check(42ULL, ULLong) 26 | 27 | checkValue(0b101010u, 42u) 28 | checkValue(0b000000101010u, 42u) 29 | checkValue(0c52u, 42u) 30 | checkValue(0x2au, 42u) 31 | 32 | "Pass" println() 33 | } 34 | 35 | -------------------------------------------------------------------------------- /test/compiler/literals/interpolated-string-literal.ooc: -------------------------------------------------------------------------------- 1 | Foo: class { 2 | init: func 3 | toString: func -> String { "Foo" } 4 | } 5 | 6 | Bar: class extends Foo { 7 | init: func 8 | toString: func -> String { "Bar" } 9 | } 10 | 11 | main: func -> Int { 12 | success := true 13 | 14 | "Testing custom toString" println() 15 | str := "#{Foo new()}#{Bar new()}" 16 | if(str != "FooBar") { 17 | "[FAIL] Final string should be FooBar, not %s" printfln(str) 18 | success = false 19 | } else { 20 | "[PASS]" println() 21 | } 22 | 23 | "Testing escape" println() 24 | str = "\#{foo}" 25 | if(str size != 6) { 26 | "[FAIL] Escaped string size should be 6, not %d" printfln(str size) 27 | success = false 28 | } else { 29 | "[PASS]" println() 30 | } 31 | 32 | success ? 0 : 1 33 | } 34 | -------------------------------------------------------------------------------- /test/compiler/literals/range-literal.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | range := 3..13 4 | expect(3, range min) 5 | expect(13, range max) 6 | } 7 | -------------------------------------------------------------------------------- /test/compiler/literals/string-literal-escapes.ooc: -------------------------------------------------------------------------------- 1 | 2 | checkString: func (test: String, ref: Int) { 3 | val := test[0] as UChar 4 | if (val != ref) { 5 | "'#{test}' should be #{ref}, is #{val}" println() 6 | exit(1) 7 | } 8 | } 9 | 10 | checkChar: func (test: Char, ref: Int) { 11 | val := test as UChar 12 | if (val != ref) { 13 | "'#{test}' should be #{ref}, is #{val}" println() 14 | exit(1) 15 | } 16 | } 17 | 18 | main: func { 19 | checkString("\0", 0) 20 | checkString("\r", 13) 21 | checkString("\n", 10) 22 | checkString("\a", 7) 23 | checkString("\t", 9) 24 | checkString("\v", 11) 25 | checkString("\377", 255) 26 | checkString("\xff", 255) 27 | 28 | checkChar('\0', 0) 29 | checkChar('\r', 13) 30 | checkChar('\n', 10) 31 | checkChar('\a', 7) 32 | checkChar('\t', 9) 33 | checkChar('\v', 11) 34 | checkChar('\377', 255) 35 | checkChar('\xff', 255) 36 | 37 | "Pass" println() 38 | } 39 | -------------------------------------------------------------------------------- /test/compiler/literals/string-literal-octal.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | success := true 4 | 5 | // https://github.com/nddrylliog/rock/issues/324 6 | "Test for #324..." println() 7 | s := "\033[36myay\033[0m" 8 | if (s size != 12) { 9 | "[FAIL] Size should be 12, is %d" printfln(s size) 10 | success = false 11 | } else { 12 | "[PASS]" println() 13 | } 14 | 15 | // https://github.com/nddrylliog/rock/issues/651 16 | "Test for #651..." println() 17 | s2 := "\163" 18 | if (s2 size != 1) { 19 | "[FAIL] Size should be 1, is %d" printfln(s2 size) 20 | success = false 21 | } else { 22 | "[PASS]" println() 23 | } 24 | 25 | exit(success ? 0 : 1) 26 | } 27 | -------------------------------------------------------------------------------- /test/compiler/literals/string-literal-raw.ooc: -------------------------------------------------------------------------------- 1 | 2 | fails := false 3 | 4 | main: func { 5 | c := c"Hi, world." 6 | checkType(c, CString) 7 | 8 | s := c toString() 9 | checkType(s, String) 10 | 11 | if (s != "Hi, world.") { 12 | "Fail! expected 'Hi, world.', got '%s'" printfln(s) 13 | fails = true 14 | } 15 | 16 | if (fails) { 17 | "We've had errors" println() 18 | exit(1) 19 | } 20 | 21 | "Pass" println() 22 | exit(0) 23 | } 24 | 25 | checkType: func (t: T, U: Class) { 26 | if (T != U) { 27 | fails = true 28 | "Fail! expected a %s, got a %s" printfln(U name, T name) 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /test/compiler/namespaces/namespaced-import-function.ooc: -------------------------------------------------------------------------------- 1 | import math into meth 2 | 3 | main: func { 4 | a := meth abs(-3) 5 | 6 | if (a != 3) { 7 | "Fail! a = %d" printfln(a) 8 | exit(1) 9 | } 10 | 11 | "Pass" println() 12 | exit(0) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /test/compiler/namespaces/namespaced-import-type.ooc: -------------------------------------------------------------------------------- 1 | import structs/ArrayList into structs 2 | 3 | main: func { 4 | a := structs ArrayList new() 5 | a add(1) 6 | a add(2) 7 | a add(3) 8 | 9 | if (a size != 3) { 10 | "Fail! a size = %d" printfln(a size) 11 | exit(1) 12 | } 13 | 14 | "Pass" println() 15 | exit(0) 16 | } 17 | 18 | -------------------------------------------------------------------------------- /test/compiler/operators/abstract-overload-member.ooc: -------------------------------------------------------------------------------- 1 | 2 | Matrix: abstract class { 3 | abstract operator [] (index: Int) -> Int 4 | 5 | getFirst: func -> Int { 6 | this[0] 7 | } 8 | } 9 | 10 | Vec3: class extends Matrix { 11 | a, b, c : Int 12 | init: func (=a, =b, =c) 13 | 14 | operator [] (index: Int) -> Int { 15 | match (index) { 16 | case 0 => a 17 | case 1 => b 18 | case 2 => c 19 | } 20 | } 21 | } 22 | 23 | main: func { 24 | matrix := Vec3 new(2, 4, 6) 25 | 26 | if(matrix getFirst() != 2 || matrix[1] != 4 || matrix[2] != 6) { 27 | "Fail!" println() 28 | exit(1) 29 | } 30 | 31 | "Pass" println() 32 | exit(0) 33 | } 34 | -------------------------------------------------------------------------------- /test/compiler/operators/array-overload-member.ooc: -------------------------------------------------------------------------------- 1 | 2 | Vec2: class { 3 | x, y: Float 4 | 5 | init: func (=x, =y) 6 | 7 | operator [] (index: Int) -> Float { 8 | match index { 9 | case 0 => x 10 | case 1 => y 11 | case => raise("Invalid index: #{index}"); 0.0 12 | } 13 | } 14 | } 15 | 16 | main: func { 17 | v1 := Vec2 new(1.0, 2.0) 18 | 19 | if (v1[0] != 1.0 || v1[1] != 2.0) { 20 | "Fail!" println() 21 | exit(1) 22 | } 23 | 24 | "Pass" println() 25 | exit(0) 26 | } 27 | 28 | -------------------------------------------------------------------------------- /test/compiler/operators/array-overload.ooc: -------------------------------------------------------------------------------- 1 | 2 | Vec2: class { 3 | x, y: Float 4 | 5 | init: func (=x, =y) 6 | } 7 | 8 | operator [] (v: Vec2, index: Int) -> Float { 9 | match index { 10 | case 0 => v x 11 | case 1 => v y 12 | case => raise("Invalid index: #{index}"); 0.0 13 | } 14 | } 15 | 16 | main: func { 17 | v1 := Vec2 new(1.0, 2.0) 18 | 19 | if (v1[0] != 1.0 || v1[1] != 2.0) { 20 | "Fail!" println() 21 | exit(1) 22 | } 23 | 24 | "Pass" println() 25 | exit(0) 26 | } 27 | 28 | -------------------------------------------------------------------------------- /test/compiler/operators/assign-numeric-and-cover.ooc: -------------------------------------------------------------------------------- 1 | 2 | fails := false 3 | 4 | main: func { 5 | one() 6 | 7 | if (fails) { 8 | "We've had failures" println() 9 | exit(1) 10 | } 11 | 12 | "Pass!" println() 13 | } 14 | 15 | TileId: cover from UInt 16 | 17 | one: func { 18 | // no value to check here 19 | (row, column) := getTileRowColumn(256 as TileId) 20 | } 21 | 22 | getTileRowColumn: func (lid: TileId) -> (SizeT, SizeT) { 23 | tilesPerRow: SizeT = 42 24 | (lid / tilesPerRow, lid % tilesPerRow) 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/compiler/operators/assign-numeric-and-reference.ooc: -------------------------------------------------------------------------------- 1 | 2 | fails := false 3 | 4 | main: func { 5 | one() 6 | two() 7 | 8 | if (fails) { 9 | "We've had failures" println() 10 | exit(1) 11 | } 12 | 13 | "Pass!" println() 14 | } 15 | 16 | one: func { 17 | a: Int = 42 18 | b: SizeT 19 | 20 | b = a 21 | if (b != 42) { 22 | "Fail! b = %d" printfln(b) 23 | fails = true 24 | } 25 | } 26 | 27 | two: func { 28 | b: SizeT 29 | assign(b&, 42) 30 | 31 | if (b != 42) { 32 | "Fail! b = %d" printfln(b) 33 | fails = true 34 | } 35 | } 36 | 37 | assign: func (b: SizeT@, a: Int) { 38 | b = a 39 | } 40 | 41 | -------------------------------------------------------------------------------- /test/compiler/operators/binaryop-array-access-side-effects.ooc: -------------------------------------------------------------------------------- 1 | SimpleStack: class { 2 | _data: T* 3 | _count: SizeT = 0 4 | _capacity: SizeT = 8 5 | init: func { this _data = gc_malloc(this _capacity * T size) } 6 | push: func (element: T) { 7 | this _data[this _count] = element 8 | this _count += 1 9 | } 10 | 11 | pop: func -> T { 12 | this _data[this _count -= 1] 13 | } 14 | } 15 | 16 | describe("binary operator and array access existance of side effects should be correctly detected", || 17 | stack := SimpleStack new() 18 | stack push(1) . push(2) . push(3) 19 | 20 | a := stack pop() 21 | stack pop() 22 | b := stack pop() 23 | 24 | expect(3, a) 25 | expect(1, b) 26 | ) 27 | -------------------------------------------------------------------------------- /test/compiler/operators/check-on-definition.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | Vec2: class { 5 | x, y: Int 6 | 7 | operator * -> This { 8 | this 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /test/compiler/operators/comparison-overload-member.ooc: -------------------------------------------------------------------------------- 1 | 2 | Number: class { 3 | x: Int 4 | 5 | init: func (=x) 6 | 7 | operator <=> (n: Number) -> Int { 8 | x <=> n x 9 | } 10 | } 11 | 12 | main: func { 13 | n1 := Number new(13) 14 | n2 := Number new(42) 15 | 16 | if (n1 > n2) { 17 | "Fail! (n1 > n2)" println() 18 | exit(1) 19 | } 20 | 21 | if (n2 < n1) { 22 | "Fail! (n2 < n1)" println() 23 | exit(1) 24 | } 25 | 26 | if (n2 == n1) { 27 | "Fail! (n2 == n1)" println() 28 | exit(1) 29 | } 30 | 31 | if (!(n2 != n1)) { 32 | "Fail! (n2 != n1)" println() 33 | exit(1) 34 | } 35 | 36 | if ((n1 <=> n2) != -1) { 37 | "Fail! (n1 <=> n2)" println() 38 | exit(1) 39 | } 40 | 41 | if ((n2 <=> n1) != 1) { 42 | "Fail! (n2 <=> n1)" println() 43 | exit(1) 44 | } 45 | 46 | "Pass" println() 47 | exit(0) 48 | } 49 | 50 | -------------------------------------------------------------------------------- /test/compiler/operators/comparison-overload.ooc: -------------------------------------------------------------------------------- 1 | 2 | Number: class { 3 | x: Int 4 | 5 | init: func (=x) 6 | } 7 | 8 | operator <=> (n1, n2: Number) -> Int { 9 | n1 x <=> n2 x 10 | } 11 | 12 | main: func { 13 | n1 := Number new(13) 14 | n2 := Number new(42) 15 | 16 | if (n1 > n2) { 17 | "Fail! (n1 > n2)" println() 18 | exit(1) 19 | } 20 | 21 | if (n2 < n1) { 22 | "Fail! (n2 < n1)" println() 23 | exit(1) 24 | } 25 | 26 | if (n2 == n1) { 27 | "Fail! (n2 == n1)" println() 28 | exit(1) 29 | } 30 | 31 | if (!(n2 != n1)) { 32 | "Fail! (n2 != n1)" println() 33 | exit(1) 34 | } 35 | 36 | if ((n1 <=> n2) != -1) { 37 | "Fail! (n1 <=> n2)" println() 38 | exit(1) 39 | } 40 | 41 | if ((n2 <=> n1) != 1) { 42 | "Fail! (n2 <=> n1)" println() 43 | exit(1) 44 | } 45 | 46 | "Pass" println() 47 | exit(0) 48 | } 49 | 50 | -------------------------------------------------------------------------------- /test/compiler/operators/invalid-abstract-overload.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | abstract operator + (l: Bool, right: Int) -> String 4 | 5 | -------------------------------------------------------------------------------- /test/compiler/operators/null-coalescing-associativity.ooc: -------------------------------------------------------------------------------- 1 | operator ?? (l, r: Int) -> Int { 2 | r 3 | } 4 | 5 | main: func { 6 | if ((1 ?? 2 ?? 3) != 3) { 7 | "Fail!" println() 8 | exit(1) 9 | } 10 | 11 | "Pass" println() 12 | exit(0) 13 | } 14 | -------------------------------------------------------------------------------- /test/compiler/operators/null-coalescing-single-evaluation.ooc: -------------------------------------------------------------------------------- 1 | 2 | counter := 0 3 | 4 | fun: func -> String { 5 | counter += 1 6 | "" 7 | } 8 | 9 | describe("Left side of the null coalescing operator should only be evaluated once", || 10 | temp := fun() ?? "foo" 11 | 12 | expect(1, counter) 13 | ) 14 | -------------------------------------------------------------------------------- /test/compiler/operators/null-coalescing.ooc: -------------------------------------------------------------------------------- 1 | main: func { 2 | a := null as String 3 | 4 | a = a ?? "test" 5 | 6 | if(a != "test") { 7 | "Fail!" println() 8 | exit(1) 9 | } 10 | 11 | "Pass" println() 12 | exit(0) 13 | } 14 | -------------------------------------------------------------------------------- /test/compiler/operators/overload-order.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/780 3 | 4 | describe("operator overload order should not matter", || 5 | p := Point2D new(2, 3) 6 | p2 := Point2D new(1, 1) 7 | p -= p2 8 | 9 | expect(1, p x) 10 | expect(2, p y) 11 | ) 12 | 13 | // Support code 14 | 15 | Point2D: class { 16 | x, y: Int 17 | init: func(=x, =y) 18 | operator - -> This { This new(-this x, -this y) } 19 | operator - (other: This) -> This { This new(this x - other x, this y - other y) } 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/compiler/operators/safe-navigation-simple.ooc: -------------------------------------------------------------------------------- 1 | Foo: cover { 2 | bar: Bar 3 | } 4 | 5 | Bar: class { 6 | baz: Baz 7 | 8 | init: func (nil? := false) { 9 | if (nil?) { 10 | baz = null 11 | } else { 12 | baz = Baz new(this) 13 | } 14 | } 15 | } 16 | 17 | Baz: class { 18 | foo: Foo 19 | 20 | init: func (bar: Bar) { 21 | foo bar = bar 22 | } 23 | } 24 | 25 | describe("safe navigation operator should navigate into classes and covers", || 26 | bar1 := Bar new() 27 | bar2 := Bar new(true) 28 | 29 | expect(bar1 $ baz $ foo bar, bar1) 30 | expect(bar2 $ baz $ foo bar, null) 31 | ) 32 | -------------------------------------------------------------------------------- /test/compiler/operators/safe-navigation-with-nullco.ooc: -------------------------------------------------------------------------------- 1 | Foo: class { 2 | bar: Bar 3 | 4 | init: func (=bar) 5 | } 6 | 7 | Bar: class { 8 | str: String 9 | 10 | init: func (=str) 11 | } 12 | 13 | describe("safe navigation and nullco operators should work in conjuction", || 14 | foo1 := Foo new(null) 15 | foo2 := Foo new(Bar new("hi")) 16 | foo3 := Foo new(Bar new(null)) 17 | 18 | expect(foo1 $ bar $ str ?? "nothing", "nothing") 19 | expect(foo2 $ bar $ str ?? "nothing", "hi") 20 | expect(foo3 $ bar $ str ?? "nullstr", "nullstr") 21 | ) 22 | -------------------------------------------------------------------------------- /test/compiler/operators/unary-minus-non-numeric.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | main: func { 4 | 5 | a := "Yay" 6 | b := -a 7 | 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /test/compiler/operators/unary-minus.ooc: -------------------------------------------------------------------------------- 1 | 2 | Vec2: class { 3 | x, y: Float 4 | 5 | init: func (=x, =y) 6 | } 7 | 8 | main: func { 9 | v1 := Vec2 new(1.0, 1.0) 10 | v2 := Vec2 new(v1 x * 1.0, - v1 y * 1.0) 11 | 12 | if (v2 x != 1.0 || v2 y != -1.0) { 13 | "Fail! v2 = #{v2 x}, #{v2 y}" println() 14 | exit(1) 15 | } 16 | 17 | "Pass" println() 18 | exit(0) 19 | } 20 | 21 | -------------------------------------------------------------------------------- /test/compiler/operators/unary-overload-member.ooc: -------------------------------------------------------------------------------- 1 | 2 | Vec2: class { 3 | x, y: Float 4 | 5 | init: func (=x, =y) 6 | 7 | operator - -> This { 8 | new(-x, -y) 9 | } 10 | 11 | operator + -> This { 12 | new(x, y) 13 | } 14 | } 15 | 16 | main: func { 17 | v1 := Vec2 new(1.0, 1.0) 18 | v2 := +v1 19 | v3 := -v1 20 | 21 | if (v2 x != 1.0 || v2 y != 1.0) { 22 | "Fail! v2 = #{v2 x}, #{v2 y}" println() 23 | exit(1) 24 | } 25 | 26 | if (v3 x != -1.0 || v3 y != -1.0) { 27 | "Fail! v3 = #{v3 x}, #{v3 y}" println() 28 | exit(1) 29 | } 30 | 31 | "Pass" println() 32 | exit(0) 33 | } 34 | 35 | -------------------------------------------------------------------------------- /test/compiler/operators/unary-overload.ooc: -------------------------------------------------------------------------------- 1 | 2 | Vec2: class { 3 | x, y: Float 4 | 5 | init: func (=x, =y) 6 | } 7 | 8 | operator - (v: Vec2) -> Vec2 { 9 | Vec2 new(-v x, -v y) 10 | } 11 | 12 | operator + (v: Vec2) -> Vec2 { 13 | Vec2 new(+v x, +v y) 14 | } 15 | 16 | main: func { 17 | v1 := Vec2 new(1.0, 1.0) 18 | v2 := +v1 19 | v3 := -v1 20 | 21 | if (v2 x != 1.0 || v2 y != 1.0) { 22 | "Fail! v2 = #{v2 x}, #{v2 y}" println() 23 | exit(1) 24 | } 25 | 26 | if (v3 x != -1.0 || v3 y != -1.0) { 27 | "Fail! v3 = #{v3 x}, #{v3 y}" println() 28 | exit(1) 29 | } 30 | 31 | "Pass" println() 32 | exit(0) 33 | } 34 | 35 | -------------------------------------------------------------------------------- /test/compiler/operators/unary-plus-non-numeric.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | main: func { 4 | 5 | a := "Yay" 6 | b := +a 7 | 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /test/compiler/operators/unary-plus.ooc: -------------------------------------------------------------------------------- 1 | 2 | Vec2: class { 3 | x, y: Float 4 | 5 | init: func (=x, =y) 6 | } 7 | 8 | main: func { 9 | v1 := Vec2 new(1.0, 1.0) 10 | v2 := Vec2 new(+ v1 x * 1.0, - v1 y * 1.0) 11 | 12 | if (v2 x != 1.0 || v2 y != -1.0) { 13 | "Fail! v2 = #{v2 x}, #{v2 y}" println() 14 | exit(1) 15 | } 16 | 17 | "Pass" println() 18 | exit(0) 19 | } 20 | 21 | -------------------------------------------------------------------------------- /test/compiler/pointers/references-accessing.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/595 3 | 4 | describe("accessing references inside closures should work", || 5 | a : Int@ = gc_malloc(Int size) 6 | a = 42 7 | f := func { 8 | expect(42, a) 9 | } 10 | f() 11 | ) 12 | -------------------------------------------------------------------------------- /test/compiler/pointers/references-assigning.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/595 3 | 4 | describe("accessing & assigning references inside closures should work", || 5 | alamanthus : Int@ = gc_malloc(Int size) 6 | alamanthus = 42 7 | f := func { 8 | expect(42, alamanthus) 9 | alamanthus = 24 10 | } 11 | f() 12 | expect(24, alamanthus) 13 | ) 14 | -------------------------------------------------------------------------------- /test/compiler/properties/call-properties.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | // Test for https://github.com/ooc-lang/rock/issues/860 5 | 6 | Foo: class { 7 | b ::= 1 8 | init: func 9 | } 10 | 11 | foo := Foo new() 12 | foo b() 13 | 14 | -------------------------------------------------------------------------------- /test/compiler/properties/extend-pdfe.ooc: -------------------------------------------------------------------------------- 1 | 2 | extend Int { 3 | plusFive ::= this + 5 4 | } 5 | 6 | extend String { 7 | hasWhitespace? ::= contains?(' ') 8 | } 9 | 10 | main: func { 11 | success? := true 12 | 13 | if(42 plusFive != 47 as Float) { 14 | success? = false 15 | "[FAIL] 42 plus five is 47, not %d" printfln(42 plusFive) 16 | } 17 | 18 | if("lolwut" hasWhitespace?) { 19 | success? = false 20 | "[FAIL] \"lolwut\" hasWhitespace? should be false, not true" println() 21 | } 22 | 23 | if (!success?) { 24 | "We've had errors" println() 25 | exit(1) 26 | } 27 | 28 | "Pass" println() 29 | } 30 | -------------------------------------------------------------------------------- /test/compiler/properties/extend-properties.ooc: -------------------------------------------------------------------------------- 1 | extend Int { 2 | plusFive: Int { 3 | get { 4 | this + 5 5 | } 6 | } 7 | } 8 | 9 | extend String { 10 | hasWhitespace?: Bool { get { this contains?(' ') } } 11 | } 12 | 13 | main: func { 14 | success? := true 15 | 16 | "Tests for #711..." println() 17 | 18 | if(42 plusFive == 47 as Float) { 19 | "[PASS]" println() 20 | } else { 21 | success? = false 22 | "[FAIL] 42 plus five is 47, not %d" printfln(42 plusFive) 23 | } 24 | 25 | 26 | if(!"lolwut" hasWhitespace?) { 27 | "[PASS]" println() 28 | } else { 29 | success? = false 30 | "[FAIL] \"lolwut\" hasWhitespace? should be false, not true" println() 31 | } 32 | 33 | exit(success? ? 0 : 1) 34 | } 35 | -------------------------------------------------------------------------------- /test/compiler/properties/no-generic-initialization-for-properties.ooc: -------------------------------------------------------------------------------- 1 | 2 | // cf. https://github.com/ooc-lang/rock/issues/840 3 | // and https://github.com/ooc-lang/rock/pull/854 4 | 5 | describe("generic properties should work", || 6 | tbar := Foo new() 7 | tbar a = 1 8 | 9 | expect(1, tbar a as Int) 10 | expect(1, tbar b) 11 | 12 | tbar b = 2 13 | 14 | expect(2, tbar a as Int) 15 | expect(2, tbar b) 16 | ) 17 | 18 | // support code 19 | 20 | Foo: class { 21 | init: func 22 | 23 | a: T 24 | b: T { 25 | get { a } 26 | set (c) { a = c } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /test/compiler/properties/operator_assign_setter.ooc: -------------------------------------------------------------------------------- 1 | foo: class{ 2 | init: func(){} 3 | a: Int = 0 4 | b: Int{ 5 | get { a } 6 | set(c){ a = c } 7 | } 8 | } 9 | 10 | foo2: cover{ 11 | init: func(){} 12 | a: Int = 0 13 | b: Int{ 14 | get { a } 15 | set(c){ a = c } 16 | } 17 | } 18 | 19 | bar := foo new() 20 | bar b += bar b + 1 21 | bar b += 1 22 | bar b = bar b + 1 23 | 24 | bar2 := foo2 new() 25 | bar2 b += bar2 b + 1 26 | bar2 b += 1 27 | bar2 b = bar2 b + 1 28 | 29 | bar b += bar2 b + bar b + 1 30 | 31 | bar b += bar2 b 32 | -------------------------------------------------------------------------------- /test/compiler/properties/pdfe-cover.ooc: -------------------------------------------------------------------------------- 1 | 2 | import math 3 | 4 | // Does not build 5 | Point: cover { 6 | x, y: Float 7 | norm ::= (this x pow(2.0f) + this y pow(2.0f)) sqrt() 8 | normToo : Float { get { (this x pow(2.0f) + this y pow(2.0f)) sqrt() } } 9 | } 10 | 11 | main: func { 12 | p := (2, 2) as Point 13 | n1 := p norm 14 | n2 := p normToo 15 | if (n1 != n2) { 16 | "Fail: expected n1 == n2, but got %f != %f" printfln(n1, n2) 17 | exit(1) 18 | } 19 | 20 | "Pass" println() 21 | } 22 | -------------------------------------------------------------------------------- /test/compiler/properties/pdfe.ooc: -------------------------------------------------------------------------------- 1 | 2 | Coyote: class { 3 | firstName := "Wile E." 4 | lastName := "Coyote" 5 | fullName ::= "#{firstName} #{lastName}" 6 | 7 | init: func 8 | } 9 | 10 | main: func { 11 | c := Coyote new() 12 | fullName := c fullName 13 | if (fullName != "Wile E. Coyote") { 14 | "Fail! fullName = %s" printfln(fullName) 15 | exit(1) 16 | } 17 | 18 | "Pass" println() 19 | } 20 | -------------------------------------------------------------------------------- /test/compiler/syntax/misplaced-oocdocs1.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | /// this is an ooc-doc, and it's misplaced 5 | 6 | /// this one is well-placed though 7 | Dog: class {} 8 | 9 | -------------------------------------------------------------------------------- /test/compiler/syntax/misplaced-oocdocs2.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | /** this is an ooc-doc, and it's misplaced */ 5 | 6 | /** this one is well-placed though */ 7 | Dog: class {} 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/compiler/syntax/oocdocs-not.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | 42 4 | //// this is not an ooc-doc, everything is fine 5 | 43 6 | /**************** 7 | * Nor is this! * 8 | ****************/ 9 | } 10 | 11 | -------------------------------------------------------------------------------- /test/compiler/syntax/version-blocks.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | version (apple) { 4 | "Apple!" println() 5 | } 6 | 7 | version (ios_simulator) { 8 | "ios simulator!" println() 9 | } 10 | 11 | version (ios) { 12 | "ios!" println() 13 | } 14 | 15 | version (osx) { 16 | "OSX!" println() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/compiler/tuples/complex-swap.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | one() 4 | 5 | "Pass" println() 6 | } 7 | 8 | one: func { 9 | a := 1 10 | b := 2 11 | (a, b) = (b, a + b) 12 | 13 | if (a != 2 || b != 3) { 14 | "Fail! (one) a = %d, b = %d" printfln(a, b) 15 | exit(1) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/compiler/tuples/ncall.ooc: -------------------------------------------------------------------------------- 1 | f: func -> (Int, Int, Int) { (1, 2, 3) } 2 | g: func -> (Int, Int, Int) { f() } 3 | 4 | main: func { 5 | (a, b, c) := g() 6 | if (a != 1 || b != 2 || c != 3) { 7 | "Fail! (a = %d, b = %d, c = %d)" printfln(a, b, c) 8 | exit(1) 9 | } 10 | 11 | "Pass" println() 12 | } 13 | -------------------------------------------------------------------------------- /test/compiler/tuples/tuple-assign.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | a, b: Int 4 | 5 | (a, b) = dup(42) 6 | if (a != 42 || b != 43) { 7 | "Fail! (a, b) = dup(42)" println() 8 | exit(1) 9 | } 10 | 11 | (b, a) = (a, b) 12 | if (b != 42 || a != 43) { 13 | "Fail! (a, b) = dup(42)" println() 14 | exit(1) 15 | } 16 | 17 | "Pass" println() 18 | } 19 | 20 | dup: func (a: Int) -> (Int, Int) { 21 | (a, a + 1) 22 | } 23 | -------------------------------------------------------------------------------- /test/compiler/tuples/tuple-assign2.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | a, b: Int 4 | 5 | (a, b) = Duplicator dup(42) 6 | if (a != 42 || b != 43) { 7 | "Fail!" println() 8 | exit(1) 9 | } 10 | 11 | "Pass" println() 12 | } 13 | 14 | Duplicator: class { 15 | dup: static func (a: Int) -> (Int, Int) { 16 | (a, a + 1) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/compiler/tuples/tuple-multidecl-omit.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | one() 4 | two() 5 | three() 6 | 7 | "Pass" println() 8 | } 9 | 10 | one: func { 11 | (a, b, _) := foo() 12 | 13 | if (a != 1 || b != 2) { 14 | "Fail! (one) a = %d, b = %d" printfln(a, b) 15 | exit(1) 16 | } 17 | } 18 | 19 | two: func { 20 | (a, _, b) := foo() 21 | 22 | if (a != 1 || b != 3) { 23 | "Fail! (two) a = %d, b = %d" printfln(a, b) 24 | exit(1) 25 | } 26 | } 27 | 28 | three: func { 29 | (_, a, b) := foo() 30 | 31 | if (a != 2 || b != 3) { 32 | "Fail! (two) a = %d, b = %d" printfln(a, b) 33 | exit(1) 34 | } 35 | } 36 | 37 | foo: func -> (Int, Int, Int) { 38 | (1, 2, 3) 39 | } 40 | 41 | -------------------------------------------------------------------------------- /test/compiler/tuples/tuple-multidecl-precedence.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/issues/903 3 | 4 | describe("tuple variable decls should have precedence over members", || 5 | bar := Foo new(1337) 6 | expect(1337, bar xolophan) 7 | expect(1337, bar yardenis) 8 | ) 9 | 10 | // support code 11 | 12 | Foo: class { 13 | xolophan := 1 14 | yardenis := 2 15 | init: func (=xolophan, =yardenis) 16 | init: func ~fromInt (input: Int) { 17 | (xolophan, yardenis) := This makeXY(input) 18 | init(xolophan, yardenis) 19 | } 20 | makeXY: static func (input: Int) -> (Int, Int) { (input, input) } 21 | } 22 | -------------------------------------------------------------------------------- /test/compiler/tuples/tuple-multidecl.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | one() 4 | two() 5 | 6 | "Pass" println() 7 | } 8 | 9 | one: func { 10 | (a, b) := ("a", "b") 11 | 12 | if (a != "a" || b != "b") { 13 | "Fail! (one) a = %s, b = %s" printfln(a, b) 14 | exit(1) 15 | } 16 | } 17 | 18 | two: func { 19 | (a, b) := dup("a") 20 | 21 | if (a != "a" || b != "a bis") { 22 | "Fail! (two) a = %s, b = %s" printfln(a, b) 23 | exit(1) 24 | } 25 | } 26 | 27 | dup: func (s: String) -> (String, String) { 28 | (s, s + " bis") 29 | } 30 | 31 | -------------------------------------------------------------------------------- /test/compiler/tuples/tuple-swap.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | 4 | a := "a" 5 | b := "b" 6 | (a, b) = (b, a) 7 | 8 | if (a == "a" || b == "b") { 9 | "Fail!" println() 10 | exit(1) 11 | } 12 | 13 | "Pass" println() 14 | 15 | } 16 | -------------------------------------------------------------------------------- /test/compiler/types/cast-to-struct.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | Vec2: cover { 4 | x, y: Float 5 | } 6 | 7 | a: Pointer 8 | a as Vec2 9 | 10 | -------------------------------------------------------------------------------- /test/compiler/types/cast-to-struct2.ooc: -------------------------------------------------------------------------------- 1 | //! shouldfail 2 | 3 | Vec2: cover { 4 | x, y: Float 5 | } 6 | 7 | a: Int* 8 | a as Vec2 9 | 10 | -------------------------------------------------------------------------------- /test/compiler/types/common-root-object.ooc: -------------------------------------------------------------------------------- 1 | 2 | //! shouldfail 3 | 4 | // This currently infers to Object[], crashes at C compile time 5 | // After change: Incompatible types Float, String (covers vs. class) 6 | a := [1, 2.0f, "String", 'v'] 7 | 8 | // a is now an Object (according to rock) 9 | a := match 'a' { 10 | case 'a' => 0 11 | case => "Hello World!" 12 | } 13 | 14 | // Kaboom! 15 | a class name println() 16 | -------------------------------------------------------------------------------- /test/compiler/variables/builtins.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("can access builtins", || 3 | __BUILD_DATETIME__ println() 4 | __BUILD_TARGET__ println() 5 | __BUILD_ROCK_VERSION__ println() 6 | __BUILD_ROCK_CODENAME__ println() 7 | __BUILD_HOSTNAME__ println() 8 | ) 9 | -------------------------------------------------------------------------------- /test/compiler/variables/class-of-any-type.ooc: -------------------------------------------------------------------------------- 1 | 2 | describe("can access 'class' of both object and primitives types", || 3 | expect("Foo", Foo new() class name) 4 | expect("Int", 42 class name) 5 | expect("String", "String" class name) 6 | ) 7 | 8 | Foo: class { 9 | init: func 10 | } 11 | -------------------------------------------------------------------------------- /test/compiler/variables/constnum.h: -------------------------------------------------------------------------------- 1 | #define _THE_GRAAL_ 1 2 | -------------------------------------------------------------------------------- /test/compiler/variables/extern-const-reference.ooc: -------------------------------------------------------------------------------- 1 | 2 | // Test for https://github.com/ooc-lang/rock/pull/897 3 | 4 | include ./constnum 5 | 6 | GRAAL: extern(_THE_GRAAL_) const Int 7 | 8 | foo: func (t: T) -> String { 9 | match t { 10 | case i: Int => 11 | "matched!" 12 | case => 13 | "error" 14 | } 15 | } 16 | 17 | describe("should know that extern const are not referencable", || 18 | expect("matched!", foo(GRAAL)) 19 | ) 20 | 21 | -------------------------------------------------------------------------------- /test/sdk/io/exists.ooc: -------------------------------------------------------------------------------- 1 | 2 | import io/File 3 | 4 | main: func { 5 | 6 | f := File new("some_unique_filename_hopefully") 7 | 8 | if (f exists?()) { 9 | "Fail! #{f path} should not exist." println() 10 | exit(1) 11 | } 12 | 13 | f write("Hello") 14 | 15 | if (!f exists?()) { 16 | "Fail! #{f path} should exist." println() 17 | exit(1) 18 | } 19 | 20 | f rm() 21 | 22 | if (f exists?()) { 23 | "Fail! #{f path} should no longer exist." println() 24 | exit(1) 25 | } 26 | 27 | "Pass" println() 28 | 29 | } 30 | -------------------------------------------------------------------------------- /test/sdk/io/fileexec.ooc: -------------------------------------------------------------------------------- 1 | 2 | import io/File 3 | 4 | main: func { 5 | version (windows) { 6 | // there's no way that test runs on Win32 7 | "Skip" println() 8 | exit(0) 9 | } 10 | 11 | f := File new("some_unique_filename_hopefully") 12 | f write("hoy hoy") 13 | 14 | if (f executable?()) { 15 | "Fail! #{f path} should not be executable" println() 16 | exit(1) 17 | } 18 | 19 | f setExecutable(true) 20 | 21 | if (!f executable?()) { 22 | "Fail! #{f path} should be executable by now" println() 23 | exit(1) 24 | } 25 | 26 | f setExecutable(false) 27 | 28 | if (f executable?()) { 29 | "Fail! #{f path} should no longer be executable at this point" println() 30 | exit(1) 31 | } 32 | 33 | f rm() 34 | 35 | "Pass" println() 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /test/sdk/io/find.ooc: -------------------------------------------------------------------------------- 1 | import io/File 2 | 3 | main: func { 4 | base := File new("find_test") 5 | 6 | dir := File new(base, "some/deep/directory/structure") 7 | dir mkdirs() 8 | 9 | f1 := File new(dir, "blah.txt") 10 | f1 write("hello") 11 | f2 := File new(base, "blah.txt") 12 | f2 write("hallo") 13 | 14 | foundCount := 0 15 | base find(f1 name, |f| 16 | foundCount += 1 17 | true 18 | ) 19 | base rm_rf() 20 | 21 | if (foundCount < 2) { 22 | "Should have found two instances of #{f1 name} in #{base path}" println() 23 | exit(1) 24 | } 25 | 26 | "Pass" println() 27 | } 28 | -------------------------------------------------------------------------------- /test/sdk/io/rm.ooc: -------------------------------------------------------------------------------- 1 | import io/File 2 | 3 | main: func { 4 | f := File new("blah.txt") 5 | f write("hello") 6 | 7 | if (!f exists?()) { 8 | "#{f path} should exist!" println() 9 | exit(1) 10 | } 11 | f rm() 12 | 13 | if (f exists?()) { 14 | "#{f path} should no longer exist!" println() 15 | exit(1) 16 | } 17 | 18 | "Pass" println() 19 | } 20 | -------------------------------------------------------------------------------- /test/sdk/io/rm_rf.ooc: -------------------------------------------------------------------------------- 1 | import io/File 2 | 3 | main: func { 4 | base := File new("rm_rf_test") 5 | 6 | dir := File new(base, "some/deep/directory/structure") 7 | dir mkdirs() 8 | 9 | if (!dir exists?()) { 10 | "#{dir path} should exist!" println() 11 | exit(1) 12 | } 13 | 14 | f1 := File new(dir, "blah.txt") 15 | f1 write("hello") 16 | f2 := File new(dir, "blih.txt") 17 | f2 write("hallo") 18 | 19 | if (!base rm_rf()) { 20 | "#{base path} rm_rf() should have returned true" println() 21 | exit(1) 22 | } 23 | 24 | checkDisappearance := func (f: File) { 25 | if (f exists?()) { 26 | "#{f path} should no longer exist!" println() 27 | exit(1) 28 | } 29 | } 30 | 31 | checkDisappearance(f1) 32 | checkDisappearance(f2) 33 | checkDisappearance(dir) 34 | checkDisappearance(base) 35 | 36 | "Pass" println() 37 | } 38 | -------------------------------------------------------------------------------- /test/sdk/lang/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !*.ooc 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /test/sdk/lang/crash.ooc: -------------------------------------------------------------------------------- 1 | //! shouldcrash 2 | 3 | // sdk 4 | import structs/[ArrayList, List] 5 | import os/Time 6 | 7 | version (windows) { 8 | RaiseException: extern func (ULong, ULong, ULong, Pointer) 9 | } 10 | 11 | foo: func { 12 | // SIGSEGV or access violation 13 | //* 14 | f: Int* = null 15 | f@ = 0 16 | //*/ 17 | 18 | // SIGFPE 19 | /* 20 | a := 30 21 | b := 0 22 | a /= b 23 | */ 24 | 25 | // Win32 exception 26 | /* 27 | RaiseException(0, 0, 0, null) 28 | */ 29 | 30 | // ooc exception 31 | /* 32 | a := ArrayList new() 33 | a[0] toString() println() 34 | */ 35 | 36 | // no crash? sleep and try again later 37 | "Sleeping..." println() 38 | Time sleepSec(2) 39 | } 40 | 41 | bar: func { 42 | foo() 43 | } 44 | 45 | main: func { 46 | // hangs on OpenBSD for some reason 47 | version (openbsd) { 48 | exit(1) 49 | } 50 | app := App new() 51 | app run() 52 | } 53 | 54 | App: class { 55 | init: func 56 | 57 | run: func { 58 | version (debug) { 59 | "Running in debug!" println() 60 | } else { 61 | "Running in release!" println() 62 | } 63 | 64 | "> Printing a gratuitious backtrace" println() 65 | Exception getCurrentBacktrace() println() 66 | 67 | "> Now looping. If it doesn't crash, use Ctrl-C to send SIGINT!" println() 68 | 69 | loop(|| 70 | runToo() 71 | true 72 | ) 73 | } 74 | 75 | runToo: func { 76 | bar() 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /test/sdk/lang/cstr.ooc: -------------------------------------------------------------------------------- 1 | 2 | a := "Hello" as CString 3 | a println() 4 | 5 | b := ("He" + "llo") as CString 6 | b println() 7 | 8 | "a = b ? %d" printfln(a equals?(b)) 9 | -------------------------------------------------------------------------------- /test/sdk/lang/limits.ooc: -------------------------------------------------------------------------------- 1 | describe("Numeric limits should be defined",|| 2 | shortMin := SHRT_MIN 3 | shortMax := SHRT_MAX 4 | unsignedShortMax := USHRT_MAX 5 | 6 | intMin := INT_MIN 7 | intMax := INT_MAX 8 | unsignedIntMax := UINT_MAX 9 | 10 | longMin := LONG_MIN 11 | longMax := LONG_MAX 12 | unsignedLongMax := ULONG_MAX 13 | 14 | longLongMin := LLONG_MIN 15 | longLongMax := LLONG_MAX 16 | unsignedLongLongMax := ULLONG_MAX 17 | 18 | floatMin := FLT_MIN 19 | floatMax := FLT_MAX 20 | 21 | doubleMin := DBL_MIN 22 | doubleMax := DBL_MAX 23 | 24 | longDoubleMin := LDBL_MIN 25 | longDoubleMax := LDBL_MAX 26 | 27 | infinity := INFINITY 28 | notANumber := NAN 29 | ) 30 | -------------------------------------------------------------------------------- /test/sdk/lang/longformat.ooc: -------------------------------------------------------------------------------- 1 | 2 | main: func { 3 | v := 0x726fdb47dd0e0e31LLU 4 | "interp #{v}" println() 5 | "%%u, %u" printfln(v) 6 | "%%lu, %lu" printfln(v) 7 | "%%llu, %llu" printfln(v) 8 | "%%x, %x" printfln(v) 9 | } 10 | -------------------------------------------------------------------------------- /test/sdk/os/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !*.ooc 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /test/sdk/os/coroutines.ooc: -------------------------------------------------------------------------------- 1 | 2 | import os/Coro 3 | 4 | main: func { 5 | // no ucontext support on openbsd 6 | version (openbsd) { 7 | exit(0) 8 | } 9 | 10 | mainCoro := Coro new() 11 | mainCoro initializeMainCoro() 12 | 13 | letter: Char 14 | 15 | coro1 := Coro new() 16 | mainCoro startCoro(coro1, || 17 | for (c in "LLAMACORE") { 18 | letter = c 19 | coro1 switchTo(mainCoro) 20 | } 21 | exit(0) 22 | ) 23 | 24 | while(true) { 25 | "%c" printfln(letter) 26 | mainCoro switchTo(coro1) 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /test/sdk/os/dynlib.ooc: -------------------------------------------------------------------------------- 1 | 2 | import os/Dynlib 3 | 4 | main: func { 5 | version (windows) { 6 | lib := Dynlib load("KERNEL32") 7 | 8 | if (!lib) { 9 | "Fail! Couldn't load library KERNEL32" println() 10 | exit(1) 11 | } 12 | 13 | cpiAddr := lib symbol("GetCurrentProcessId") 14 | 15 | cpi := (cpiAddr, null) as Func () -> ULong 16 | 17 | "GetCurrentProcessId = %d" printfln(cpi()) 18 | 19 | lib close() 20 | } else { 21 | lib := Dynlib load("libm") 22 | 23 | if (!lib) { 24 | "Fail! Couldn't load library libm" println() 25 | exit(1) 26 | } 27 | 28 | cosAddr := lib symbol("cos") 29 | 30 | cos := (cosAddr, null) as Func (Double) -> Double 31 | 32 | "cos(PI / 4) = %.3f" printfln(cos(3.14 * 0.25)) 33 | 34 | lib close() 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /test/sdk/os/filedesc.ooc: -------------------------------------------------------------------------------- 1 | import os/FileDescriptor 2 | 3 | STDOUT_FILENO write("out") 4 | STDERR_FILENO write("err") 5 | -------------------------------------------------------------------------------- /test/sdk/os/pipe1.ooc: -------------------------------------------------------------------------------- 1 | import os/Pipe 2 | 3 | main: func { 4 | pipe := Pipe new() 5 | 6 | pipe write("Hello") 7 | pipe read(128) println() 8 | pipe close('r'). close('w') 9 | } 10 | -------------------------------------------------------------------------------- /test/sdk/os/pipe1b.ooc: -------------------------------------------------------------------------------- 1 | import os/Pipe 2 | 3 | main: func { 4 | pipe := Pipe new() 5 | 6 | pipe write("Hello") 7 | 8 | buf := Buffer new() 9 | pipe read(buf) 10 | 11 | pipe close() 12 | 13 | buf println() 14 | } 15 | -------------------------------------------------------------------------------- /test/sdk/os/pipe2.ooc: -------------------------------------------------------------------------------- 1 | import os/[Pipe, Time], threading/Thread 2 | 3 | main: func { 4 | pipe := Pipe new() 5 | 6 | reader := Thread new(|| 7 | while (!pipe eof?()) { 8 | result := pipe read(128) 9 | if (result) result print() 10 | } 11 | pipe close('r') 12 | ) 13 | 14 | writer := Thread new(|| 15 | for (i in 0..10) { 16 | pipe write("Hello %d\n" format(i)) 17 | Time sleepMilli(100) 18 | } 19 | pipe close('w') 20 | ) 21 | 22 | reader start() 23 | writer start() 24 | 25 | reader wait() 26 | writer wait() 27 | 28 | "Pass!" println() 29 | } 30 | -------------------------------------------------------------------------------- /test/sdk/os/pool.ooc: -------------------------------------------------------------------------------- 1 | import os/[Process, JobPool], math/Random 2 | 3 | pool := JobPool new() 4 | "Default parallelism = %d" printfln(pool parallelism) 5 | 6 | for (i in 0..3) { 7 | duration := 0.1 * Random randInt(1, 4) 8 | "Sleeping for %.1fs" printfln(duration) 9 | 10 | args := ["sleep", "#{duration}"] 11 | version (windows) { 12 | args = ["cmd", "/c", "ver"] 13 | } 14 | 15 | p := Process new(args) 16 | p executeNoWait() 17 | pool add(Job new(p)) 18 | } 19 | 20 | pool waitAll() 21 | "Pass" println() 22 | 23 | -------------------------------------------------------------------------------- /test/sdk/os/process.ooc: -------------------------------------------------------------------------------- 1 | import os/Process 2 | 3 | main: func { 4 | p: Process 5 | version (windows) { 6 | p = Process new(["cmd", "/c", "ver"]) 7 | } else { 8 | p = Process new(["cat", "/etc/hosts"]) 9 | } 10 | p execute() 11 | } 12 | -------------------------------------------------------------------------------- /test/sdk/os/processcwd.ooc: -------------------------------------------------------------------------------- 1 | import os/Process 2 | 3 | main: func { 4 | version (windows) { 5 | p := Process new(["cmd", "/c", "echo %TMP%"]) 6 | tmpDir := p getOutput() 7 | tmpDir = tmpDir trim() 8 | 9 | p = Process new(["cmd", "/c", "cd"]) 10 | p setCwd(tmpDir) 11 | cwd := p getOutput() 12 | cwd = cwd trim() 13 | 14 | if (cwd != tmpDir) { 15 | "Fail! expected cwd to equal #{tmpDir}, but got #{cwd} instead" println() 16 | exit(1) 17 | } 18 | } else { 19 | p := Process new(["cat", "hosts"]) 20 | p setCwd("/etc") 21 | p execute() 22 | } 23 | 24 | "Pass" println() 25 | } 26 | -------------------------------------------------------------------------------- /test/sdk/os/processenv.ooc: -------------------------------------------------------------------------------- 1 | import os/Process, structs/HashMap 2 | 3 | main: func { 4 | env := HashMap new() 5 | env put("MYVAR", "42") 6 | 7 | command := ["bash", "-c", "echo $MYVAR"] 8 | version (windows) { 9 | command = ["cmd", "/c", "echo %MYVAR%"] 10 | } 11 | 12 | p := Process new(command) 13 | p setEnv(env) 14 | p execute() 15 | output := p getOutput() 16 | output = output trim() 17 | if (output != "42") { 18 | "Fail! expected output = 42, but got #{output}" println() 19 | exit(1) 20 | } 21 | 22 | "Pass" println() 23 | } 24 | -------------------------------------------------------------------------------- /test/sdk/os/processinvalid.ooc: -------------------------------------------------------------------------------- 1 | import os/Process 2 | 3 | main: func { 4 | version (windows) { 5 | p := Process new(["i_do_not_exist/some_exec"]) 6 | caught := false 7 | try { 8 | p execute() 9 | } catch (p: ProcessException) { 10 | caught = true 11 | } 12 | 13 | if (!caught) { 14 | "Fail! expected a ProcessException to be thrown" println() 15 | exit(1) 16 | } 17 | 18 | "Pass" println() 19 | } else { 20 | p := Process new(["i_do_not_exist/some_exec"]) 21 | code := p execute() 22 | 23 | if (code == 0) { 24 | "Fail! expected non-zero code but got #{code}" println() 25 | exit(1) 26 | } 27 | 28 | "Pass" println() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/sdk/os/shell.ooc: -------------------------------------------------------------------------------- 1 | import os/ShellUtils 2 | 3 | file := ShellUtils findExecutable("autoconf") 4 | match file { 5 | case null => "autoconf not found!" 6 | case => "found: %s" format(file path) 7 | } println() 8 | 9 | -------------------------------------------------------------------------------- /test/sdk/structs/double-remove.ooc: -------------------------------------------------------------------------------- 1 | import structs/[ArrayList] 2 | 3 | main: func { 4 | a := [1, 2, 3] as ArrayList 5 | iter := a iterator() 6 | x := iter next() 7 | 8 | iter remove() 9 | try { 10 | iter remove() 11 | } catch { 12 | "All good!" println() 13 | exit(0) 14 | } 15 | 16 | // should never reach here 17 | "Woops, ArrayListIterator is unsafe..." println() 18 | exit(1) 19 | } 20 | -------------------------------------------------------------------------------- /test/sdk/structs/multimap_iterator_test.ooc: -------------------------------------------------------------------------------- 1 | 2 | import structs/[HashMap, MultiMap] 3 | 4 | main: func { 5 | testMap(MultiMap new(), "123456") 6 | testMap(HashMap new(), "246") 7 | 8 | "Pass" println() 9 | } 10 | 11 | testMap: func (map: HashMap, control: String) { 12 | map put("a", "1") 13 | map put("a", "2") 14 | map put("b", "3") 15 | map put("b", "4") 16 | map put("c", "5") 17 | map put("c", "6") 18 | 19 | result := "" 20 | for (v in map) { 21 | result = result + v 22 | } 23 | 24 | if (result != control) { 25 | "Fail! for #{map class name} should be #{control}, is #{result}" println() 26 | exit(1) 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /test/sdk/text/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !*.ooc 3 | !.gitignore 4 | !json 5 | -------------------------------------------------------------------------------- /test/sdk/text/json/dsl.ooc: -------------------------------------------------------------------------------- 1 | import text/json/DSL into dsl 2 | 3 | main: func { 4 | result := dsl make(|make| 5 | make object( 6 | "key", "value", 7 | "yay", 3, 8 | "array", make array( 9 | "yesss maaaan", 10 | 1327, 11 | false 12 | ), 13 | "another", make object( 14 | "fancy", "object", 15 | "VERY", 1337 16 | ) 17 | ) 18 | ) 19 | 20 | if (!result || result empty?()) { 21 | "Fail! result = %s" printfln(result) 22 | exit(1) 23 | } 24 | 25 | "Pass" println() 26 | exit(0) 27 | } 28 | -------------------------------------------------------------------------------- /test/sdk/text/json/null-as-string.ooc: -------------------------------------------------------------------------------- 1 | import structs/HashBag 2 | import text/json/Generator 3 | 4 | obj := HashBag new() 5 | obj put("version", null as String) 6 | 7 | s := generateString(obj) 8 | s println() 9 | if(s != "{\"version\":null}") { 10 | "Fail" println() 11 | exit(1) 12 | } else { 13 | "Pass" println() 14 | exit(0) 15 | } 16 | -------------------------------------------------------------------------------- /test/sdk/text/shlex-test.ooc: -------------------------------------------------------------------------------- 1 | 2 | import text/Shlex 3 | import structs/ArrayList 4 | 5 | main: func { 6 | args := "rock 'is kinda' \"fun don't\" you think" 7 | tokens := Shlex split(args) 8 | 9 | check := func (index: Int, value: String) { 10 | if (tokens[index] != value) { 11 | "Fail! expected tokens[#{index}] == #{value}, but got #{tokens[index]}" println() 12 | exit(1) 13 | } 14 | } 15 | 16 | if (tokens size != 5) { 17 | "Fail! expected 5 tokens, got #{tokens size}" println() 18 | exit(1) 19 | } 20 | check(0, "rock") 21 | check(1, "is kinda") 22 | check(2, "fun don't") 23 | check(3, "you") 24 | check(4, "think") 25 | 26 | "Pass" println() 27 | 28 | } 29 | -------------------------------------------------------------------------------- /test/sdk/threading/mutex.ooc: -------------------------------------------------------------------------------- 1 | import threading/Thread 2 | import structs/ArrayList 3 | 4 | counter := 0 5 | 6 | mutex := Mutex new() 7 | 8 | threads := ArrayList new() 9 | for (i in 0..10) { 10 | threads add(Thread new(|| 11 | for (i in 0..1000) { 12 | mutex with(|| 13 | counter += 1 14 | ) 15 | Thread yield() 16 | } 17 | )) 18 | } 19 | 20 | for (t in threads) t start() 21 | for (t in threads) t wait() 22 | 23 | // prints counter = 10000 24 | "counter = %d" printfln(counter) 25 | 26 | if (counter != 10000) exit(1) 27 | -------------------------------------------------------------------------------- /test/sdk/threading/recmutex.ooc: -------------------------------------------------------------------------------- 1 | import threading/Thread 2 | import structs/ArrayList 3 | 4 | threads := ArrayList new() 5 | 6 | mutex := RecursiveMutex new() 7 | counter := 0 8 | 9 | for (i in 0..42) { 10 | threads add(Thread new(|| 11 | for (i in 0..10) mutex lock() 12 | counter += 1 13 | for (i in 0..10) mutex unlock() 14 | )) 15 | } 16 | 17 | for (t in threads) t start() 18 | for (t in threads) t wait() 19 | 20 | // prints counter = 42 21 | "counter = %d" printfln(counter) 22 | 23 | -------------------------------------------------------------------------------- /test/sdk/threading/threadlocal.ooc: -------------------------------------------------------------------------------- 1 | import threading/Thread 2 | import structs/ArrayList 3 | 4 | val := ThreadLocal new(42) 5 | 6 | threads := ArrayList new() 7 | for (i in 1..3) { 8 | threads add(Thread new(|| 9 | val set(i) 10 | )) 11 | } 12 | 13 | for (t in threads) t start() 14 | for (t in threads) t wait() 15 | 16 | // prints val = 42 17 | "val = %d" printfln(val get()) 18 | 19 | if (val get() != 42) exit(1) 20 | -------------------------------------------------------------------------------- /utils/clean-whitespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR=$(dirname $(readlink -f $0)) # Directory script is in 4 | cd $DIR/.. 5 | 6 | find -name "*.ooc" -exec sed -ir 's/^ *$//g' {} \; 7 | -------------------------------------------------------------------------------- /utils/download-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | echo "Getting latest bootstrap url..." 3 | URL=`curl -s 'https://api.github.com/repos/ooc-lang/rock/releases' | grep 'bootstrap-only' | grep 'browser_download_url' | head -1 | cut -d '"' -f 4` 4 | if [ -z "${URL}" ]; then 5 | echo "Could not find latest bootstrap-only. Can you reach api.github.com ?" 6 | exit 1 7 | fi 8 | 9 | echo "Downloading from ${URL}" 10 | curl -L ${URL} | tar xjm 1>/dev/null 11 | -------------------------------------------------------------------------------- /utils/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Pre-commit hook run by git before a commit is made. 4 | # Copy to .git/hooks 5 | 6 | tmp="$(mktemp)" 7 | 8 | git diff --cached --name-only | while read file; do 9 | if [[ "${file:(-4):4}" == ".ooc" ]]; then 10 | oldsize=$(stat "$file" -c "%s") 11 | sed -ri 's/\t/ /g' "$file" 12 | newsize1=$(stat "$file" -c "%s") 13 | sed -ri 's/\s+$//g' "$file" 14 | newsize2=$(stat "$file" -c "%s") 15 | 16 | # Need two size checks because the first sed call actually adds spaces 17 | # whereas the second one drops them. 18 | 19 | if [[ "$oldsize" != "$newsize1" || "$newsize1" != "$newsize2" ]]; then 20 | echo 1 > $tmp 21 | echo "Fixed whitespaces for : '$file'" 22 | fi 23 | fi 24 | done 25 | 26 | modified=$(cat $tmp) 27 | rm $tmp 28 | 29 | if [[ "$modified" == "1" ]]; then 30 | echo "Run git diff to verify that the changes are correct, then commit." 31 | echo "Don't forget to run git add on the fixed files or use git commit -a." 32 | echo "(Note: to temporary disable this script, pass the -n flag to git commit)" 33 | exit 1 34 | fi 35 | -------------------------------------------------------------------------------- /utils/rock-script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ROCK_PATH=/path/to/rock 3 | export OOC_DIST=/path/to/ooc 4 | export OOC_SDK=${ROCK_PATH}/custom-sdk 5 | ${ROCK_PATH}/bin/rock $* 6 | -------------------------------------------------------------------------------- /vendor/README.md: -------------------------------------------------------------------------------- 1 | We used to provide binary builds of boehm-gc, but then it suddenly occured 2 | to us that it was evil and that it was easier to just provide the sources and 3 | build it in the bootstrap target. 4 | 5 | So that's what we do now. 6 | -------------------------------------------------------------------------------- /vendor/gc/Mac_files/dataend.c: -------------------------------------------------------------------------------- 1 | /* 2 | dataend.c 3 | 4 | A hack to get the extent of global data for the Macintosh. 5 | 6 | by Patrick C. Beard. 7 | */ 8 | 9 | long __dataend; 10 | -------------------------------------------------------------------------------- /vendor/gc/Mac_files/datastart.c: -------------------------------------------------------------------------------- 1 | /* 2 | datastart.c 3 | 4 | A hack to get the extent of global data for the Macintosh. 5 | 6 | by Patrick C. Beard. 7 | */ 8 | 9 | long __datastart; 10 | -------------------------------------------------------------------------------- /vendor/gc/autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | set -e 4 | 5 | # These version are ok, pre-1.7 is not. Post 1.7 may produce a lot of 6 | # warnings for unrelated projects, so prefer 1.7 for now. 7 | am_version= 8 | for v in 1.10 1.9 1.8 1.7; do 9 | if type -p &>/dev/null automake-$v; then 10 | am_version="-$v" 11 | break 12 | fi 13 | done 14 | if [ -z "$am_version" ]; then 15 | case "`automake --version`" in 16 | *\ 0.*|*\ 1.[0-6].*|*\ 1.[0-6]\ *) 17 | echo "$0: Automake-1.7 or later is needed." 18 | exit 2 19 | ;; 20 | esac 21 | fi 22 | 23 | set -x 24 | aclocal$am_version 25 | autoconf 26 | autoheader 27 | automake$am_version -ac 28 | libtoolize --automake --force 29 | set +x 30 | echo 31 | echo "Ready to run './configure'." 32 | echo 33 | -------------------------------------------------------------------------------- /vendor/gc/bdw-gc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: Boehm-Demers-Weiser Conservative Garbage Collector 7 | Description: A garbage collector for C and C++ 8 | Version: @PACKAGE_VERSION@ 9 | Libs: -L${libdir} -lgc 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /vendor/gc/build_atomic_ops.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | P=`pwd`/libatomic_ops-install 3 | cd libatomic_ops 4 | ./configure --prefix=$P 5 | $MAKE CC=$CC install 6 | -------------------------------------------------------------------------------- /vendor/gc/build_atomic_ops.sh.cygwin: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # We install through the temporary directory in case pwd contains spaces, 3 | # which otherwise breaks the build machinery. 4 | # This is a gross hack and probably breaks incremental rebuilds 5 | mkdir libatomic_ops-install 6 | P=`pwd` 7 | Q=`mktemp -d` 8 | ln -s "$P" $Q/dir 9 | cd $Q/dir/libatomic_ops 10 | ./configure --prefix=$Q/dir/libatomic_ops-install 11 | $MAKE CC=$CC install 12 | cd / 13 | rm $Q/dir 14 | rmdir $Q 15 | -------------------------------------------------------------------------------- /vendor/gc/callprocs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | GC_DEBUG=1 3 | export GC_DEBUG 4 | $* 2>&1 | awk '{print "0x3e=c\""$0"\""};/^\t##PC##=/ {if ($2 != 0) {print $2"?i"}}' | adb $1 | sed "s/^ >/>/" 5 | -------------------------------------------------------------------------------- /vendor/gc/cord/cord.am: -------------------------------------------------------------------------------- 1 | 2 | lib_LTLIBRARIES += libcord.la 3 | 4 | libcord_la_LIBADD = $(top_builddir)/libgc.la 5 | libcord_la_LDFLAGS = -version-info 1:3:0 -no-undefined 6 | 7 | libcord_la_SOURCES = \ 8 | cord/cordbscs.c \ 9 | cord/cordprnt.c \ 10 | cord/cordtest.c \ 11 | cord/cordxtra.c 12 | 13 | 14 | EXTRA_DIST += \ 15 | cord/cordbscs.c cord/cordtest.c cord/de.c \ 16 | cord/cordprnt.c cord/cordxtra.c cord/de_cmds.h \ 17 | cord/de_win.h cord/de_win.c cord/de_win.RC cord/de_win.ICO 18 | 19 | pkginclude_HEADERS += include/cord.h 20 | -------------------------------------------------------------------------------- /vendor/gc/cord/de_cmds.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | /* Boehm, May 19, 1994 2:24 pm PDT */ 14 | 15 | #ifndef DE_CMDS_H 16 | 17 | # define DE_CMDS_H 18 | 19 | # define UP 16 /* ^P */ 20 | # define DOWN 14 /* ^N */ 21 | # define LEFT 2 /* ^B */ 22 | # define RIGHT 6 /* ^F */ 23 | # define DEL 127 /* ^? */ 24 | # define BS 8 /* ^H */ 25 | # define UNDO 21 /* ^U */ 26 | # define WRITE 23 /* ^W */ 27 | # define QUIT 4 /* ^D */ 28 | # define REPEAT 18 /* ^R */ 29 | # define LOCATE 12 /* ^L */ 30 | # define TOP 20 /* ^T */ 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /vendor/gc/cord/de_win.ICO: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooc-lang/rock/079f9b970e2bf33bfa613c670c3d88cea99ac26e/vendor/gc/cord/de_win.ICO -------------------------------------------------------------------------------- /vendor/gc/doc/README.Mac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ooc-lang/rock/079f9b970e2bf33bfa613c670c3d88cea99ac26e/vendor/gc/doc/README.Mac -------------------------------------------------------------------------------- /vendor/gc/doc/README.MacOSX: -------------------------------------------------------------------------------- 1 | See README.darwin for the latest Darwin/MacOSX information. 2 | -------------------------------------------------------------------------------- /vendor/gc/doc/README.OS2: -------------------------------------------------------------------------------- 1 | The code assumes static linking, and a single thread. The editor de has 2 | not been ported. The cord test program has. The supplied OS2_MAKEFILE 3 | assumes the IBM C Set/2 environment, but the code shouldn't. 4 | 5 | Since we haven't figured out hoe to do perform partial links or to build static 6 | libraries, clients currently need to link against a long list of executables. 7 | -------------------------------------------------------------------------------- /vendor/gc/doc/README.cmake: -------------------------------------------------------------------------------- 1 | 2 | CMAKE 3 | ----- 4 | 5 | Win32 binaries (both 32- and 64-bit) can be built using CMake. CMake is an 6 | open-source tool like automake - it generates makefiles. 7 | 8 | Some preliminary work has been done to make this work on other platforms, but 9 | the support is not yet complete. 10 | 11 | CMake will generate: 12 | 13 | Borland Makefiles 14 | MSYS Makefiles 15 | MinGW Makefiles 16 | NMake Makefiles 17 | Unix Makefiles 18 | . Visual Studio project files 19 | Visual Studio 6 20 | Visual Studio 7 21 | Visual Studio 7 .NET 2003 22 | Visual Studio 8 2005 23 | Visual Studio 8 2005 Win64 24 | Visual Studio 9 2008 25 | Visual Studio 9 2008 Win64 26 | Watcom WMake 27 | 28 | 29 | BUILD PROCESS 30 | ------------- 31 | 32 | . install cmake (cmake.org) 33 | . add directory containing cmake.exe to %PATH% 34 | . run cmake from the gc root directory, passing the target with -G: 35 | eg. 36 | > cmake -G "Visual Studio 8 2005" 37 | use the gc.sln file generated by cmake to build gc 38 | . you can also run cmake from a build directory to build outside of 39 | the source tree. Just specify the path to the source tree: 40 | eg. 41 | > mkdir build 42 | > cd build 43 | > cmake .. -G "Visual Studio 8 2005" 44 | 45 | 46 | INPUT 47 | ----- 48 | 49 | The main input to cmake are the CMakeLists.txt files in each directory. For 50 | help, goto cmake.org. 51 | -------------------------------------------------------------------------------- /vendor/gc/doc/README.dj: -------------------------------------------------------------------------------- 1 | [Original version supplied by Xiaokun Zhu ] 2 | [This version came mostly from Gary Leavens. ] 3 | 4 | Look first at Makefile.dj, and possibly change the definitions of 5 | RM and MV if you don't have rm and mv installed. 6 | Then use Makefile.dj to compile the garbage collector. 7 | For example, you can do: 8 | 9 | make -f Makefile.dj test 10 | 11 | All the tests should work fine. 12 | 13 | -------------------------------------------------------------------------------- /vendor/gc/doc/README.hp: -------------------------------------------------------------------------------- 1 | Dynamic loading support requires that executables be linked with -ldld. 2 | The alternative is to build the collector without defining DYNAMIC_LOADING 3 | in gcconfig.h and ensuring that all garbage collectible objects are 4 | accessible without considering statically allocated variables in dynamic 5 | libraries. 6 | 7 | The collector should compile with either plain cc or cc -Ae. Cc -Aa 8 | fails to define _HPUX_SOURCE and thus will not configure the collector 9 | correctly. 10 | 11 | Incremental collection support was reccently added, and should now work. 12 | 13 | In spite of past claims, pthread support under HP/UX 11 should now work. 14 | Define GC_HPUX_THREADS for the build. Incremental collection still does not 15 | work in combination with it. 16 | 17 | The stack finding code can be confused by putenv calls before collector 18 | initialization. Call GC_malloc or GC_init before any putenv calls. 19 | -------------------------------------------------------------------------------- /vendor/gc/doc/README.rs6000: -------------------------------------------------------------------------------- 1 | We have so far failed to find a good way to determine the stack base. 2 | It is highly recommended that GC_stackbottom be set explicitly on program 3 | startup. The supplied value sometimes causes failure under AIX 4.1, though 4 | it appears to work under 3.X. HEURISTIC2 seems to work under 4.1, but 5 | involves a substantial performance penalty, and will fail if there is 6 | no limit on stack size. 7 | 8 | There is no thread support. (I assume recent versions of AIX provide 9 | pthreads? I no longer have access to a machine ...) 10 | -------------------------------------------------------------------------------- /vendor/gc/doc/README.uts: -------------------------------------------------------------------------------- 1 | Alistair Crooks supplied the port. He used Lexa C version 2.1.3 with 2 | -Xa to compile. 3 | -------------------------------------------------------------------------------- /vendor/gc/doc/README.win64: -------------------------------------------------------------------------------- 1 | 64-bit Windows on AMD64/Intel EM64T is somewhat supported in the 7.0 2 | and later release. A collector can be built with Microsoft Visual C++ 2005 3 | or with mingw-w64 gcc. 4 | More testing would clearly be helpful. 5 | 6 | NT_X64_STATIC_THREADS_MAKEFILE has been used in 7 | this environment. Copy this file to MAKEFILE, and then type "nmake" 8 | in a Visual C++ command line window to build the static library 9 | and the usual test programs. To verify that the collector is 10 | at least somewhat functional, run gctest.exe. This should create 11 | gctest.gc.log after a few seconds. 12 | 13 | This process is completely analogous to NT_STATIC_THREADS_MAKEFILE 14 | for the 32-bit version. 15 | 16 | A similar procedure using NT_X64_THREADS_MAKEFILE should be usable to 17 | build the dynamic library. Test_cpp.exe did not seem to run correctly this 18 | way. It seems that we're getting the wrong instances of operator new/delete 19 | in some cases. The C tests seemed OK. 20 | 21 | Note that currently a few warnings are still generated by default, 22 | and a number of others have been explicitly turned off in the makefile. 23 | 24 | VC++ note: to suppress warnings use -D_CRT_SECURE_NO_DEPRECATE. 25 | 26 | gcc note: -fno-strict-aliasing should be used if optimizing. 27 | -------------------------------------------------------------------------------- /vendor/gc/extra/add_gc_prefix.c: -------------------------------------------------------------------------------- 1 | # include 2 | # include 3 | 4 | #ifndef GC_ALPHA_VERSION 5 | # define GC_ALPHA_VERSION GC_TMP_ALPHA_VERSION 6 | #endif 7 | 8 | int main(argc, argv, envp) 9 | int argc; 10 | char ** argv; 11 | char ** envp; 12 | { 13 | int i; 14 | 15 | for (i = 1; i < argc; i++) { 16 | if (GC_ALPHA_VERSION == GC_NOT_ALPHA) { 17 | printf("gc%d.%d/%s ", GC_VERSION_MAJOR, GC_VERSION_MINOR, argv[i]); 18 | } else { 19 | printf("gc%d.%dalpha%d/%s ", GC_VERSION_MAJOR, 20 | GC_VERSION_MINOR, GC_ALPHA_VERSION, argv[i]); 21 | } 22 | } 23 | return(0); 24 | } 25 | -------------------------------------------------------------------------------- /vendor/gc/extra/gcname.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef GC_ALPHA_VERSION 5 | # define GC_ALPHA_VERSION GC_TMP_ALPHA_VERSION 6 | #endif 7 | 8 | int main() 9 | { 10 | if (GC_ALPHA_VERSION == GC_NOT_ALPHA) { 11 | printf("gc%d.%d", GC_VERSION_MAJOR, GC_VERSION_MINOR); 12 | } else { 13 | printf("gc%d.%dalpha%d", GC_VERSION_MAJOR, 14 | GC_VERSION_MINOR, GC_ALPHA_VERSION); 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /vendor/gc/extra/if_mach.c: -------------------------------------------------------------------------------- 1 | /* Conditionally execute a command based on machine and OS from gcconfig.h */ 2 | 3 | # include "private/gcconfig.h" 4 | # include 5 | # include 6 | # include 7 | 8 | int main(int argc, char **argv, char **envp) 9 | { 10 | if (argc < 4) goto Usage; 11 | if (strcmp(MACH_TYPE, argv[1]) != 0) return(0); 12 | if (strcmp(OS_TYPE, "") != 0 && strcmp(argv[2], "") != 0 13 | && strcmp(OS_TYPE, argv[2]) != 0) return(0); 14 | fprintf(stderr, "^^^^Starting command^^^^\n"); 15 | fflush(stdout); 16 | execvp(argv[3], argv+3); 17 | perror("Couldn't execute"); 18 | 19 | Usage: 20 | fprintf(stderr, "Usage: %s mach_type os_type command\n", argv[0]); 21 | fprintf(stderr, "Currently mach_type = %s, os_type = %s\n", 22 | MACH_TYPE, OS_TYPE); 23 | return(1); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /vendor/gc/extra/if_not_there.c: -------------------------------------------------------------------------------- 1 | /* Conditionally execute a command based if the file argv[1] doesn't exist */ 2 | /* Except for execvp, we stick to ANSI C. */ 3 | # include "private/gcconfig.h" 4 | # include 5 | # include 6 | # include 7 | #ifdef __DJGPP__ 8 | #include 9 | #endif /* __DJGPP__ */ 10 | 11 | int main(int argc, char **argv, char **envp) 12 | { 13 | FILE * f; 14 | #ifdef __DJGPP__ 15 | DIR * d; 16 | #endif /* __DJGPP__ */ 17 | if (argc < 3) goto Usage; 18 | if ((f = fopen(argv[1], "rb")) != 0 19 | || (f = fopen(argv[1], "r")) != 0) { 20 | fclose(f); 21 | return(0); 22 | } 23 | #ifdef __DJGPP__ 24 | if ((d = opendir(argv[1])) != 0) { 25 | closedir(d); 26 | return(0); 27 | } 28 | #endif 29 | printf("^^^^Starting command^^^^\n"); 30 | fflush(stdout); 31 | execvp(argv[2], argv+2); 32 | exit(1); 33 | 34 | Usage: 35 | fprintf(stderr, "Usage: %s file_name command\n", argv[0]); 36 | return(1); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /vendor/gc/gc_cpp.cpp: -------------------------------------------------------------------------------- 1 | // Visual C++ seems to prefer a .cpp extension to .cc 2 | #include "gc_cpp.cc" 3 | -------------------------------------------------------------------------------- /vendor/gc/ia64_save_regs_in_stack.s: -------------------------------------------------------------------------------- 1 | .text 2 | .align 16 3 | .global GC_save_regs_in_stack 4 | .proc GC_save_regs_in_stack 5 | GC_save_regs_in_stack: 6 | .body 7 | flushrs 8 | ;; 9 | mov r8=ar.bsp 10 | br.ret.sptk.few rp 11 | .endp GC_save_regs_in_stack 12 | 13 | -------------------------------------------------------------------------------- /vendor/gc/include/extra/gc.h: -------------------------------------------------------------------------------- 1 | /* This file is installed for backward compatibility. */ 2 | #include 3 | -------------------------------------------------------------------------------- /vendor/gc/include/extra/gc_cpp.h: -------------------------------------------------------------------------------- 1 | /* This file is installed for backward compatibility. */ 2 | #include 3 | -------------------------------------------------------------------------------- /vendor/gc/include/gc_amiga_redirects.h: -------------------------------------------------------------------------------- 1 | #ifndef GC_AMIGA_REDIRECTS_H 2 | 3 | # define GC_AMIGA_REDIRECTS_H 4 | 5 | # if ( defined(_AMIGA) && !defined(GC_AMIGA_MAKINGLIB) ) 6 | extern void *GC_amiga_realloc(void *old_object,size_t new_size_in_bytes); 7 | # define GC_realloc(a,b) GC_amiga_realloc(a,b) 8 | extern void GC_amiga_set_toany(void (*func)(void)); 9 | extern int GC_amiga_free_space_divisor_inc; 10 | extern void *(*GC_amiga_allocwrapper_do) \ 11 | (size_t size,void *(*AllocFunction)(size_t size2)); 12 | # define GC_malloc(a) \ 13 | (*GC_amiga_allocwrapper_do)(a,GC_malloc) 14 | # define GC_malloc_atomic(a) \ 15 | (*GC_amiga_allocwrapper_do)(a,GC_malloc_atomic) 16 | # define GC_malloc_uncollectable(a) \ 17 | (*GC_amiga_allocwrapper_do)(a,GC_malloc_uncollectable) 18 | # define GC_malloc_stubborn(a) \ 19 | (*GC_amiga_allocwrapper_do)(a,GC_malloc_stubborn) 20 | # define GC_malloc_atomic_uncollectable(a) \ 21 | (*GC_amiga_allocwrapper_do)(a,GC_malloc_atomic_uncollectable) 22 | # define GC_malloc_ignore_off_page(a) \ 23 | (*GC_amiga_allocwrapper_do)(a,GC_malloc_ignore_off_page) 24 | # define GC_malloc_atomic_ignore_off_page(a) \ 25 | (*GC_amiga_allocwrapper_do)(a,GC_malloc_atomic_ignore_off_page) 26 | # endif /* _AMIGA && !GC_AMIGA_MAKINGLIB */ 27 | 28 | #endif /* GC_AMIGA_REDIRECTS_H */ 29 | 30 | 31 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/AUTHORS: -------------------------------------------------------------------------------- 1 | Originally written by Hans Boehm, with some platform-dependent code 2 | imported from the Boehm-Demers-Weiser GC, where it was contributed 3 | by many others. 4 | 5 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = src doc tests 2 | 3 | pkgconfigdir = $(libdir)/pkgconfig 4 | pkgconfig_DATA = pkgconfig/atomic_ops.pc 5 | noinst_DATA = pkgconfig/atomic_ops-uninstalled.pc 6 | 7 | #distclean-local: 8 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/NEWS: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/doc/Makefile.am: -------------------------------------------------------------------------------- 1 | # installed documentation 2 | # 3 | dist_pkgdata_DATA=COPYING LICENSING.txt README.txt README_stack.txt README_malloc.txt README_win32.txt 4 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/doc/README_win32.txt: -------------------------------------------------------------------------------- 1 | Most of the atomic_ops functionality is available under Win32 with 2 | the Microsoft tools, but the build process currently is considerably more 3 | primitive than on Linux/Unix platforms. 4 | 5 | To build: 6 | 7 | 1) Go to the src directory in the distribution. 8 | 2) Make sure the Microsoft command-line tools (e.g. nmake) are available. 9 | 3) Run "nmake -f Makefile.msft". This should run some tests, which 10 | may print warnings about the types of the "Interlocked" functions. 11 | I haven't been able to make all versions of VC++ happy. If you know 12 | how to, please send a patch. 13 | 4) To compile applications, you will need to retain or copy the following 14 | pieces from the resulting src directory contents: 15 | "atomic_ops.h" - Header file defining low-level primitives. This 16 | includes files from: 17 | "atomic_ops"- Subdirectory containing implementation header files. 18 | "atomic_ops_stack.h" - Header file describing almost lock-free stack. 19 | "atomic_ops_malloc.h" - Header file describing almost lock-free malloc. 20 | "libatomic_ops_gpl.lib" - Library containing implementation of the 21 | above two. The atomic_ops.h implementation 22 | is entirely in the header files in Win32. 23 | 24 | Most clients of atomic_ops.h will need to define AO_ASSUME_WINDOWS98 before 25 | including it. Compare_and_swap is otherwise not available. 26 | 27 | Note that the library is covered by the GNU General Public License, while 28 | the top 2 of these pieces allow use in proprietary code. 29 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/pkgconfig/atomic_ops-uninstalled.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | top_builddir=@abs_top_builddir@ 4 | top_srcdir=@abs_top_srcdir@ 5 | 6 | Name: The atomic_ops library (uninstalled) 7 | Description: Atomic memory update operations 8 | Version: @PACKAGE_VERSION@ 9 | Libs: ${top_builddir}/src/libatomic_ops.la 10 | Cflags: -I${top_builddir}/src -I${top_srcdir}/src 11 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/pkgconfig/atomic_ops.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: The atomic_ops project 7 | Description: Atomic memory update operations portable implementation 8 | Version: @PACKAGE_VERSION@ 9 | Libs: -L${libdir} -latomic_ops 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS=atomic_ops 2 | 3 | AM_CFLAGS=@PICFLAG@ 4 | AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src 5 | 6 | include_HEADERS=atomic_ops.h atomic_ops_stack.h atomic_ops_malloc.h 7 | lib_LIBRARIES = libatomic_ops.a libatomic_ops_gpl.a 8 | if NEED_ASM 9 | libatomic_ops_a_SOURCES = atomic_ops.c atomic_ops_sysdeps.S 10 | else 11 | libatomic_ops_a_SOURCES = atomic_ops.c 12 | endif 13 | 14 | libatomic_ops_gpl_a_SOURCES = atomic_ops_stack.c atomic_ops_malloc.c 15 | 16 | EXTRA_DIST=Makefile.msft 17 | 18 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/atomic_ops/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS=sysdeps 2 | 3 | EXTRA_DIST=generalize-small.template 4 | 5 | BUILT_SOURCES = generalize-small.h 6 | 7 | #Private Headers 8 | private_HEADERS=generalize.h generalize-small.h 9 | privatedir=${includedir}/atomic_ops/ 10 | 11 | generalize-small.h: generalize-small.template 12 | sed -e s:XSIZE:char:g -e s:XCTYPE:char:g $? > $@ 13 | sed -e s:XSIZE:short:g -e s:XCTYPE:short:g $? >> $@ 14 | sed -e s:XSIZE:int:g -e s:XCTYPE:int:g $? >> $@ 15 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/atomic_ops/sysdeps/Makefile.am: -------------------------------------------------------------------------------- 1 | #General sysdep utility headers, followed by the arch-specific ones 2 | nobase_sysdep_HEADERS= generic_pthread.h \ 3 | atomic_load_store.h \ 4 | aligned_atomic_load_store.h \ 5 | acquire_release_volatile.h \ 6 | char_acquire_release_volatile.h \ 7 | char_atomic_load_store.h \ 8 | short_acquire_release_volatile.h \ 9 | short_aligned_atomic_load_store.h \ 10 | short_atomic_load_store.h \ 11 | int_acquire_release_volatile.h \ 12 | int_aligned_atomic_load_store.h \ 13 | int_atomic_load_store.h \ 14 | all_acquire_release_volatile.h \ 15 | all_aligned_atomic_load_store.h \ 16 | all_atomic_load_store.h \ 17 | read_ordered.h \ 18 | ordered_except_wr.h \ 19 | ordered.h \ 20 | ao_t_is_int.h \ 21 | test_and_set_t_is_ao_t.h \ 22 | test_and_set_t_is_char.h \ 23 | emul_cas.h \ 24 | standard_ao_double_t.h \ 25 | README \ 26 | \ 27 | armcc/arm_v6.h \ 28 | \ 29 | gcc/alpha.h gcc/arm.h gcc/avr32.h gcc/cris.h \ 30 | gcc/hexagon.h gcc/hppa.h gcc/ia64.h gcc/m68k.h \ 31 | gcc/mips.h gcc/powerpc.h gcc/s390.h \ 32 | gcc/sh.h gcc/sparc.h gcc/x86.h gcc/x86_64.h \ 33 | \ 34 | hpc/hppa.h hpc/ia64.h \ 35 | \ 36 | ibmc/powerpc.h \ 37 | \ 38 | icc/ia64.h \ 39 | \ 40 | msftc/arm.h msftc/common32_defs.h msftc/x86.h \ 41 | msftc/x86_64.h \ 42 | \ 43 | sunc/sparc.h sunc/x86.h sunc/x86_64.h 44 | 45 | sysdepdir= ${includedir}/atomic_ops/sysdeps 46 | 47 | # A few architectures require special .S files 48 | EXTRA_DIST = sunc/sparc.S 49 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/atomic_ops/sysdeps/README: -------------------------------------------------------------------------------- 1 | There are two kinds of entities in this directory: 2 | 3 | - Subdirectories corresponding to specific compilers (or compiler/OS combinations). 4 | Each of these includes one or more architecture-specific headers. 5 | 6 | - More generic header files corresponding to a particular ordering and/or 7 | atomicity property that might be shared by multiple hardware platforms. 8 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/atomic_ops/sysdeps/all_atomic_load_store.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004 Hewlett-Packard Development Company, L.P. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | /* 24 | * Describes architectures on which AO_t, unsigned char, unsigned short, 25 | * and unsigned int loads and stores are atomic for all normally legal 26 | * alignments. 27 | */ 28 | #include "atomic_load_store.h" 29 | #include "char_atomic_load_store.h" 30 | #include "short_atomic_load_store.h" 31 | #include "int_atomic_load_store.h" 32 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/atomic_ops/sysdeps/gcc/sh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 by Takashi YOSHII. All rights reserved. 3 | * 4 | * 5 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 6 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 7 | * 8 | * Permission is hereby granted to use or copy this program 9 | * for any purpose, provided the above notices are retained on all copies. 10 | * Permission to modify the code and to distribute modified code is granted, 11 | * provided the above notices are retained, and a notice that the code was 12 | * modified is included with the above copyright notice. 13 | */ 14 | 15 | #include "../all_atomic_load_store.h" 16 | #include "../ordered.h" 17 | 18 | /* sh has tas.b(byte) only */ 19 | #include "../test_and_set_t_is_char.h" 20 | 21 | AO_INLINE AO_TS_VAL_t 22 | AO_test_and_set_full(volatile AO_TS_t *addr) 23 | { 24 | int oldval; 25 | __asm__ __volatile__( 26 | "tas.b @%1; movt %0" 27 | : "=r" (oldval) 28 | : "r" (addr) 29 | : "t", "memory"); 30 | return oldval? AO_TS_CLEAR : AO_TS_SET; 31 | } 32 | #define AO_HAVE_test_and_set_full 33 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/atomic_ops/sysdeps/ordered.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003 Hewlett-Packard Development Company, L.P. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | /* These are common definitions for architectures that provide */ 24 | /* processor ordered memory operations. */ 25 | 26 | #include "ordered_except_wr.h" 27 | 28 | AO_INLINE void 29 | AO_nop_full(void) 30 | { 31 | AO_compiler_barrier(); 32 | } 33 | #define AO_HAVE_nop_full 34 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/atomic_ops/sysdeps/standard_ao_double_t.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NEC LE-IT: For 64-bit OS we extend the double type to hold two int64's 3 | * 4 | * x86-64 (except for x32): __m128 serves as placeholder which also requires 5 | * the compiler to align it on 16 byte boundary (as required by cmpxchg16). 6 | * Similar things could be done for PowerPC 64-bit using a VMX data type... 7 | */ 8 | 9 | #if ((defined(__x86_64__) && __GNUC__ >= 4) || defined(_WIN64)) \ 10 | && !defined(__ILP32__) 11 | # include 12 | typedef __m128 double_ptr_storage; 13 | #elif defined(_WIN32) && !defined(__GNUC__) 14 | typedef unsigned __int64 double_ptr_storage; 15 | #else 16 | typedef unsigned long long double_ptr_storage; 17 | #endif 18 | # define AO_HAVE_DOUBLE_PTR_STORAGE 19 | 20 | typedef union { 21 | double_ptr_storage AO_whole; 22 | struct {AO_t AO_v1; AO_t AO_v2;} AO_parts; 23 | } AO_double_t; 24 | 25 | #define AO_HAVE_double_t 26 | #define AO_val1 AO_parts.AO_v1 27 | #define AO_val2 AO_parts.AO_v2 28 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/atomic_ops/sysdeps/sunc/sparc.S: -------------------------------------------------------------------------------- 1 | .seg "text" 2 | .globl AO_test_and_set_full 3 | AO_test_and_set_full: 4 | retl 5 | ldstub [%o0],%o0 6 | -------------------------------------------------------------------------------- /vendor/gc/libatomic_ops/src/atomic_ops_sysdeps.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Include the appropriate system-dependent assembly file, if any. 3 | * This is used only if the platform supports neither inline assembly 4 | * code, nor appropriate compiler intrinsics. 5 | */ 6 | 7 | #if !defined(__GNUC__) && (defined(sparc) || defined(__sparc)) 8 | # include "atomic_ops/sysdeps/sunc/sparc.S" 9 | #endif 10 | -------------------------------------------------------------------------------- /vendor/gc/m4/ltversion.m4: -------------------------------------------------------------------------------- 1 | # ltversion.m4 -- version numbers -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # @configure_input@ 11 | 12 | # serial 3337 ltversion.m4 13 | # This file is part of GNU Libtool 14 | 15 | m4_define([LT_PACKAGE_VERSION], [2.4.2]) 16 | m4_define([LT_PACKAGE_REVISION], [1.3337]) 17 | 18 | AC_DEFUN([LTVERSION_VERSION], 19 | [macro_version='2.4.2' 20 | macro_revision='1.3337' 21 | _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) 22 | _LT_DECL(, macro_revision, 0) 23 | ]) 24 | -------------------------------------------------------------------------------- /vendor/gc/mips_sgi_mach_dep.s: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | /* This file must be preprocessed. But the SGI assembler always does */ 4 | /* that. Furthermore, a generic preprocessor won't do, since some of */ 5 | /* the SGI-supplied include files rely on behavior of the MIPS */ 6 | /* assembler. Hence we treat and name this file as though it required */ 7 | /* no preprocessing. */ 8 | 9 | # define call_push(x) move $4,x; jal GC_push_one 10 | 11 | .option pic2 12 | .text 13 | /* Mark from machine registers that are saved by C compiler */ 14 | # define FRAMESZ 32 15 | # define RAOFF FRAMESZ-SZREG 16 | # define GPOFF FRAMESZ-(2*SZREG) 17 | NESTED(GC_push_regs, FRAMESZ, ra) 18 | .mask 0x80000000,-SZREG # inform debugger of saved ra loc 19 | move t0,gp 20 | SETUP_GPX(t8) 21 | PTR_SUBU sp,FRAMESZ 22 | # ifdef SETUP_GP64 23 | SETUP_GP64(GPOFF, GC_push_regs) 24 | # endif 25 | SAVE_GP(GPOFF) 26 | REG_S ra,RAOFF(sp) 27 | # if (_MIPS_SIM == _ABIO32) 28 | call_push($2) 29 | call_push($3) 30 | # endif 31 | call_push($16) 32 | call_push($17) 33 | call_push($18) 34 | call_push($19) 35 | call_push($20) 36 | call_push($21) 37 | call_push($22) 38 | call_push($23) 39 | call_push($30) 40 | REG_L ra,RAOFF(sp) 41 | # ifdef RESTORE_GP64 42 | RESTORE_GP64 43 | # endif 44 | PTR_ADDU sp,FRAMESZ 45 | j ra 46 | .end GC_push_regs 47 | -------------------------------------------------------------------------------- /vendor/gc/mips_ultrix_mach_dep.s: -------------------------------------------------------------------------------- 1 | # define call_push(x) move $4,x; jal GC_push_one 2 | 3 | .text 4 | # Mark from machine registers that are saved by C compiler 5 | .globl GC_push_regs 6 | .ent GC_push_regs 7 | GC_push_regs: 8 | subu $sp,8 ## Need to save only return address 9 | sw $31,4($sp) 10 | .mask 0x80000000,-4 11 | .frame $sp,8,$31 12 | call_push($2) 13 | call_push($3) 14 | call_push($16) 15 | call_push($17) 16 | call_push($18) 17 | call_push($19) 18 | call_push($20) 19 | call_push($21) 20 | call_push($22) 21 | call_push($23) 22 | call_push($30) 23 | lw $31,4($sp) 24 | addu $sp,8 25 | j $31 26 | .end GC_push_regs 27 | -------------------------------------------------------------------------------- /vendor/gc/real_malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers 3 | * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. 4 | * 5 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 6 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 7 | * 8 | * Permission is hereby granted to use or copy this program 9 | * for any purpose, provided the above notices are retained on all copies. 10 | * Permission to modify the code and to distribute modified code is granted, 11 | * provided the above notices are retained, and a notice that the code was 12 | * modified is included with the above copyright notice. 13 | */ 14 | 15 | # ifdef HAVE_CONFIG_H 16 | # include "private/config.h" 17 | # endif 18 | 19 | # ifdef PCR 20 | /* 21 | * This definition should go in its own file that includes no other 22 | * header files. Otherwise, we risk not getting the underlying system 23 | * malloc. 24 | */ 25 | # define PCR_NO_RENAME 26 | # include 27 | 28 | void * real_malloc(size_t size) 29 | { 30 | return(malloc(size)); 31 | } 32 | 33 | # else 34 | 35 | extern int GC_quiet; 36 | /* ANSI C doesn't allow translation units to be empty. */ 37 | /* So we guarantee this one is nonempty. */ 38 | 39 | #endif /* PCR */ 40 | -------------------------------------------------------------------------------- /vendor/gc/sparc_netbsd_mach_dep.s: -------------------------------------------------------------------------------- 1 | ! SPARCompiler 3.0 and later apparently no longer handles 2 | ! asm outside functions. So we need a separate .s file 3 | ! This is only set up for SunOS 4. 4 | ! Assumes this is called before the stack contents are 5 | ! examined. 6 | 7 | #include "machine/asm.h" 8 | 9 | .seg "text" 10 | .globl _C_LABEL(GC_save_regs_in_stack) 11 | .globl _C_LABEL(GC_push_regs) 12 | _C_LABEL(GC_save_regs_in_stack): 13 | _C_LABEL(GC_push_regs): 14 | ta 0x3 ! ST_FLUSH_WINDOWS 15 | mov %sp,%o0 16 | retl 17 | nop 18 | 19 | .globl _C_LABEL(GC_clear_stack_inner) 20 | _C_LABEL(GC_clear_stack_inner): 21 | mov %sp,%o2 ! Save sp 22 | add %sp,-8,%o3 ! p = sp-8 23 | clr %g1 ! [g0,g1] = 0 24 | add %o1,-0x60,%sp ! Move sp out of the way, 25 | ! so that traps still work. 26 | ! Includes some extra words 27 | ! so we can be sloppy below. 28 | loop: 29 | std %g0,[%o3] ! *(long long *)p = 0 30 | cmp %o3,%o1 31 | bgu loop ! if (p > limit) goto loop 32 | add %o3,-8,%o3 ! p -= 8 (delay slot) 33 | retl 34 | mov %o2,%sp ! Restore sp., delay slot 35 | -------------------------------------------------------------------------------- /vendor/gc/sparc_sunos4_mach_dep.s: -------------------------------------------------------------------------------- 1 | ! SPARCompiler 3.0 and later apparently no longer handles 2 | ! asm outside functions. So we need a separate .s file 3 | ! This is only set up for SunOS 4. 4 | ! Assumes this is called before the stack contents are 5 | ! examined. 6 | 7 | .seg "text" 8 | .globl _GC_save_regs_in_stack 9 | .globl _GC_push_regs 10 | _GC_save_regs_in_stack: 11 | _GC_push_regs: 12 | ta 0x3 ! ST_FLUSH_WINDOWS 13 | mov %sp,%o0 14 | retl 15 | nop 16 | 17 | .globl _GC_clear_stack_inner 18 | _GC_clear_stack_inner: 19 | mov %sp,%o2 ! Save sp 20 | add %sp,-8,%o3 ! p = sp-8 21 | clr %g1 ! [g0,g1] = 0 22 | add %o1,-0x60,%sp ! Move sp out of the way, 23 | ! so that traps still work. 24 | ! Includes some extra words 25 | ! so we can be sloppy below. 26 | loop: 27 | std %g0,[%o3] ! *(long long *)p = 0 28 | cmp %o3,%o1 29 | bgu loop ! if (p > limit) goto loop 30 | add %o3,-8,%o3 ! p -= 8 (delay slot) 31 | retl 32 | mov %o2,%sp ! Restore sp., delay slot 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /vendor/gc/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | # Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | # Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | # Copyright (c) 2000-2010 by Hewlett-Packard Company. All rights reserved. 6 | ## 7 | # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 8 | # OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 9 | ## 10 | # Permission is hereby granted to use or copy this program 11 | # for any purpose, provided the above notices are retained on all copies. 12 | # Permission to modify the code and to distribute modified code is granted, 13 | # provided the above notices are retained, and a notice that the code was 14 | # modified is included with the above copyright notice. 15 | ## 16 | 17 | ADD_DEFINITIONS(-DGC_NOT_DLL) 18 | ADD_EXECUTABLE(gctest WIN32 test.c) 19 | TARGET_LINK_LIBRARIES(gctest gc-lib) 20 | -------------------------------------------------------------------------------- /vendor/gc/tests/leak_test.c: -------------------------------------------------------------------------------- 1 | #include "leak_detector.h" 2 | 3 | int main(void) { 4 | int *p[10]; 5 | int i; 6 | GC_set_find_leak(1); /* for new collect versions not compiled */ 7 | /* with -DFIND_LEAK. */ 8 | 9 | GC_INIT(); /* Needed if thread-local allocation is enabled. */ 10 | /* FIXME: This is not ideal. */ 11 | for (i = 0; i < 10; ++i) { 12 | p[i] = malloc(sizeof(int)+i); 13 | } 14 | CHECK_LEAKS(); 15 | for (i = 1; i < 10; ++i) { 16 | free(p[i]); 17 | } 18 | for (i = 0; i < 9; ++i) { 19 | p[i] = malloc(sizeof(int)+i); 20 | } 21 | CHECK_LEAKS(); 22 | CHECK_LEAKS(); 23 | CHECK_LEAKS(); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /vendor/gc/tests/middle.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test at the boundary between small and large objects. 3 | * Inspired by a test case from Zoltan Varga. 4 | */ 5 | #include "gc.h" 6 | #include 7 | 8 | int main (void) 9 | { 10 | int i; 11 | 12 | GC_set_all_interior_pointers(0); 13 | GC_INIT(); 14 | 15 | for (i = 0; i < 20000; ++i) { 16 | GC_malloc_atomic (4096); 17 | GC_malloc (4096); 18 | } 19 | for (i = 0; i < 20000; ++i) { 20 | GC_malloc_atomic (2048); 21 | GC_malloc (2048); 22 | } 23 | printf("Final heap size is %lu\n", (unsigned long)GC_get_heap_size()); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /vendor/gc/tests/realloc_test.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "gc.h" 5 | 6 | #define COUNT 10000000 7 | 8 | int main(void) { 9 | int i; 10 | unsigned long last_heap_size = 0; 11 | 12 | GC_INIT(); 13 | 14 | for (i = 0; i < COUNT; i++) { 15 | int **p = GC_MALLOC(sizeof(int *)); 16 | int *q = GC_MALLOC_ATOMIC(sizeof(int)); 17 | 18 | if (p == 0 || *p != 0) { 19 | fprintf(stderr, "GC_malloc returned garbage (or NULL)\n"); 20 | exit(1); 21 | } 22 | 23 | *p = GC_REALLOC(q, 2 * sizeof(int)); 24 | 25 | if (i % 10 == 0) { 26 | unsigned long heap_size = (unsigned long)GC_get_heap_size(); 27 | if (heap_size != last_heap_size) { 28 | printf("Heap size: %lu\n", heap_size); 29 | last_heap_size = heap_size; 30 | } 31 | } 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /vendor/gc/tests/smash_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test that overwrite error detection works reasonably. 3 | */ 4 | #define GC_DEBUG 5 | #include "gc.h" 6 | 7 | #include 8 | 9 | #define COUNT 7000 10 | #define SIZE 40 11 | 12 | char * A[COUNT]; 13 | 14 | int main(void) 15 | { 16 | int i; 17 | char *p; 18 | 19 | GC_INIT(); 20 | 21 | for (i = 0; i < COUNT; ++i) { 22 | A[i] = p = GC_MALLOC(SIZE); 23 | 24 | if (i%3000 == 0) GC_gcollect(); 25 | if (i%5678 == 0 && p != 0) p[SIZE + i/2000] = 42; 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /vendor/gc/tests/staticrootslib.c: -------------------------------------------------------------------------------- 1 | 2 | /* This test file is intended to be compiled into a DLL. */ 3 | 4 | #include 5 | 6 | #ifndef GC_DEBUG 7 | # define GC_DEBUG 8 | #endif 9 | 10 | #include "gc.h" 11 | 12 | struct treenode { 13 | struct treenode *x; 14 | struct treenode *y; 15 | } * root[10]; 16 | 17 | struct treenode * libsrl_mktree(int i) 18 | { 19 | struct treenode * r = GC_MALLOC(sizeof(struct treenode)); 20 | if (0 == i) return 0; 21 | if (1 == i) r = GC_MALLOC_ATOMIC(sizeof(struct treenode)); 22 | if (r) { 23 | r -> x = libsrl_mktree(i-1); 24 | r -> y = libsrl_mktree(i-1); 25 | } 26 | return r; 27 | } 28 | 29 | void * libsrl_init(void) 30 | { 31 | GC_INIT(); 32 | return GC_MALLOC(sizeof(struct treenode)); 33 | } 34 | -------------------------------------------------------------------------------- /vendor/gc/tests/staticrootstest.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifndef GC_DEBUG 6 | # define GC_DEBUG 7 | #endif 8 | 9 | #include "gc.h" 10 | #include "gc_backptr.h" 11 | 12 | struct treenode { 13 | struct treenode *x; 14 | struct treenode *y; 15 | } * root[10]; 16 | 17 | static char *staticroot = 0; 18 | 19 | extern struct treenode * libsrl_mktree(int i); 20 | extern void * libsrl_init(void); 21 | 22 | /* 23 | struct treenode * mktree(int i) { 24 | struct treenode * r = GC_MALLOC(sizeof(struct treenode)); 25 | if (0 == i) return 0; 26 | if (1 == i) r = GC_MALLOC_ATOMIC(sizeof(struct treenode)); 27 | r -> x = mktree(i-1); 28 | r -> y = mktree(i-1); 29 | return r; 30 | }*/ 31 | 32 | int main(void) 33 | { 34 | int i; 35 | /*GC_INIT(); 36 | staticroot = GC_MALLOC(sizeof(struct treenode));*/ 37 | staticroot = libsrl_init(); 38 | memset(staticroot, 0x42, sizeof(struct treenode)); 39 | GC_gcollect(); 40 | for (i = 0; i < 10; ++i) { 41 | root[i] = libsrl_mktree(12); 42 | GC_gcollect(); 43 | } 44 | for (i = 0; i < (int)sizeof(struct treenode); ++i) { 45 | if (staticroot[i] != 0x42) 46 | return -1; 47 | } 48 | for (i = 0; i < 10; ++i) { 49 | root[i] = libsrl_mktree(12); 50 | GC_gcollect(); 51 | } 52 | for (i = 0; i < (int)sizeof(struct treenode); ++i) { 53 | if (staticroot[i] != 0x42) 54 | return -1; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /vendor/gc/tests/trace_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef GC_DEBUG 5 | # define GC_DEBUG 6 | #endif 7 | 8 | #include "gc.h" 9 | #include "gc_backptr.h" 10 | 11 | struct treenode { 12 | struct treenode *x; 13 | struct treenode *y; 14 | } * root[10]; 15 | 16 | struct treenode * mktree(int i) { 17 | struct treenode * r = GC_MALLOC(sizeof(struct treenode)); 18 | if (0 == i) return 0; 19 | if (1 == i) r = GC_MALLOC_ATOMIC(sizeof(struct treenode)); 20 | if (r == NULL) { 21 | printf("Out of memory\n"); 22 | exit(1); 23 | } 24 | r -> x = mktree(i-1); 25 | r -> y = mktree(i-1); 26 | return r; 27 | } 28 | 29 | int main(void) 30 | { 31 | int i; 32 | GC_INIT(); 33 | for (i = 0; i < 10; ++i) { 34 | root[i] = mktree(12); 35 | } 36 | GC_generate_random_backtrace(); 37 | GC_generate_random_backtrace(); 38 | GC_generate_random_backtrace(); 39 | GC_generate_random_backtrace(); 40 | return 0; 41 | } 42 | --------------------------------------------------------------------------------