Files
hi-language.github.io/index.html

324 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html><html lang=en>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Hi Language</title>
<link rel=preconnect href=https://cdn.jsdelivr.net>
<script src=https://cdn.tailwindcss.com></script>
<link rel=stylesheet href="https://cdn.jsdelivr.net/npm/github-markdown-css@5.8.1/github-markdown-light.min.css">
<link rel=stylesheet href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.11.1/build/styles/github.min.css">
<style>
:root{--sbw:18rem}
*{scroll-behavior:smooth}
.markdown-body{font-size:16px;line-height:1.7}
.markdown-body pre{overflow:auto}
.markdown-body code:not(pre code){background:rgba(175,184,193,.2);padding:.2em .4em;border-radius:6px}
.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{scrollbar-width:none}
.btn{transition:.15s transform}.btn:active{transform:scale(.98)}
.anchor{scroll-margin-top:76px}
pre{position:relative;border:1px solid #e5e7eb;border-radius:.75rem}
.code-actions{position:absolute;top:.5rem;right:.5rem;display:flex;gap:.5rem;align-items:center}
.copy-btn{background:#0f172a;color:#fff;border-radius:.5rem;padding:.2rem .5rem;font-size:.75rem;opacity:.9}
.char-c{font-size:.75rem;color:#64748b}
@media (max-width:480px){.char-c{display:none}}
.anchor-link{margin-left:.5rem;color:#9ca3af;text-decoration:none}
.anchor-link:hover{color:#6b7280}
@media (min-width:1024px){.lg\:grid-cols-layout{grid-template-columns:var(--sbw) 1fr}}
</style>
</head>
<body class="bg-white text-gray-900 selection:bg-black/10">
<header class="sticky top-0 z-30 bg-white/80 backdrop-blur border-b border-gray-200">
<div class="mx-auto w-full px-4 py-3 grid grid-cols-3 items-center">
<button id=menuBtn class="h-9 w-9 rounded-xl bg-gray-100 hover:bg-gray-200 flex items-center justify-center btn" title="Menu"><svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M3 12h18M3 18h18"/></svg></button>
<div class="justify-self-center text-base font-semibold select-none pointer-events-none">Hi</div>
<div class="justify-self-end"></div>
</div>
</header>
<div class="grid lg:grid-cols-layout">
<aside class="hidden lg:block border-r border-gray-200 min-h-[calc(100dvh-56px)]">
<div class="p-3 border-b flex items-center gap-2"><span class="h-7 w-7 rounded-full bg-gray-900 text-white inline-flex items-center justify-center"></span><span class="font-medium truncate">Hi</span></div>
<nav id="sideNav" class="p-2 text-sm no-scrollbar overflow-y-auto max-h-[calc(100dvh-56px-49px)] space-y-1"></nav>
</aside>
<main class="min-h-[calc(100dvh-56px)] overflow-y-auto no-scrollbar">
<section id="hero" class="px-6 sm:px-8 py-10 border-b">
<div class="max-w-3xl mx-auto">
<h1 class="text-3xl sm:text-4xl font-bold tracking-tight">Hi — a corely symbolic language</h1>
<p class="mt-3 text-gray-600">Inspired by JavaScript. Few keywords, many symbols. Designed so the core reads naturally across languages, for the whole world.</p>
<div class="mt-4 flex flex-wrap gap-2">
<a href="#hello-world" class="px-3 py-1.5 rounded-full bg-gray-900 text-white text-sm btn">Get started</a>
<a href="https://github.com/hi-language" class="px-3 py-1.5 rounded-full bg-gray-100 hover:bg-gray-200 text-sm btn" target=_blank rel=noopener><svg xmlns="http://www.w3.org/2000/svg" class="inline -mt-0.5 mr-1" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 .5A12 12 0 0 0 0 12.64a12.15 12.15 0 0 0 8.2 11.55c.6.11.82-.27.82-.6v-2.17c-3.34.74-4.05-1.65-4.05-1.65a3.29 3.29 0 0 0-1.36-1.82c-1.1-.78.09-.77.09-.77a2.6 2.6 0 0 1 1.89 1.29 2.64 2.64 0 0 0 3.61 1 2.66 2.66 0 0 1 .78-1.65c-2.67-.31-5.47-1.36-5.47-6.06A4.8 4.8 0 0 1 6 7.57a4.45 4.45 0 0 1 .12-3.29s1-.33 3.3 1.26a11.39 11.39 0 0 1 6 0c2.3-1.59 3.3-1.26 3.3-1.26.44 1.03.48 2.2.12 3.29a4.79 4.79 0 0 1 1.27 3.32c0 4.72-2.8 5.75-5.47 6.06a2.97 2.97 0 0 1 .84 2.31v3.43c0 .34.22.73.83.6A12.16 12.16 0 0 0 24 12.64 12 12 0 0 0 12 .5Z"/></svg>GitHub</a>
</div>
</div>
</section>
<section id="suneHtml" class="px-6 sm:px-8 py-8"></section>
</main>
</div>
<!-- Mobile left sidebar -->
<div id="overlay" class="fixed inset-0 z-40 bg-black/30 transition-opacity opacity-0 pointer-events-none"></div>
<aside id="sidebarMobile" class="fixed inset-y-0 left-0 z-50 w-[min(85vw,var(--sbw))] max-w-[85vw] bg-white border-r border-gray-200 shadow-xl transform transition-transform duration-200 ease-out -translate-x-full">
<div class="p-3 border-b flex items-center gap-2"><span class="h-7 w-7 rounded-full bg-gray-900 text-white inline-flex items-center justify-center"></span><span class="font-medium truncate">Hi</span></div>
<nav id="sideNavMobile" class="p-2 text-sm overflow-y-auto no-scrollbar"></nav>
</aside>
<script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.11.1/build/highlight.min.js"></script>
<!-- Author docs in Markdown; use ~~~ fences -->
<script id=md type="text/markdown">
Meet Hi a corely symbolic language inspired by JavaScript.
It keeps the core mostly symbols and uses keywords only where theyre truly practical.
- Minimal surface: prefer symbols over words.
- Blocks are both objects and functions.
- Privacy with `#private` members.
- Boolean is truthiness by value (see below).
> Print helper: `_()` writes to the console.
## Hello, world
~~~js
// Hello World in Hi
_("Hi world")
~~~
## Declarations and Assignment
- `:` declares a name.
- `=` assigns or mutates a value.
~~~js
greeting: "Hi"
name: "Orion"
greeting = greeting + ", " + name
_(greeting) // "Hi, Orion"
~~~
## Blocks (object + function in one)
In Hi, `{}` is a Block. It can hold properties and executable code.
A Block is both an object and a function at the same time.
### Function Block
~~~js
sayHi: {
_("Hi")
}
sayHi() // invokes the block
~~~
### Object Block
Public vs private fields; `#` marks private members.
~~~js
player: {
name: "Orion" // public
#hp: 100 // private
}
_(player.name) // "Orion"
// _(player.#hp) // error: private
~~~
### Hybrid Block
Blocks can expose methods and hold private state.
~~~js
counter: {
#value: 0
inc: {
#value = #value + 1
_("The count is now: " + #value)
#value // last expression returns
}
}
counter.inc() // "The count is now: 1"
counter.inc() // "The count is now: 2"
~~~
### Parameters and returns
- Parameters use `(name, ...)` before the Block.
- Like Rust, the last expression is returned (no `return` keyword).
~~~js
withParams: (str) {
_(str)
str // returned
}
add: (a, b) { a + b }
_( add(2, 3) ) // 5
~~~
## Truthiness and Equality
Truthiness is value-based:
~~~js
0 // falsy (the official false)
!0 // truthy (the official true)
4 // truthy
"" // falsy (truthy if non-empty)
{} // falsy (truthy if it has content)
[] // falsy (truthy if it has content)
-0 // falsy / null / undefined (represents “empty”)
~~~
Equality:
~~~js
== // equivalent to JS ===
~~~
## Conditionals (ternary-style Blocks)
A conditional is an expression that selects a Block.
~~~js
// if
(cond) ? { /* then */ }
// if / else
(cond) ? { /* then */ } : { /* else */ }
// expression result is the last Blocks last expression
tern: (cond) ? { "A" } : { "B" }
~~~
Multi-branch:
~~~js
score: 85
grade: (score > 90) ? { "A" }
: (score > 80) ? { "B" }
: { "C" }
_(grade) // "B"
~~~
## Arrays
~~~js
primes: [2, 3, 5, 7]
// Access
firstPrime: primes[0]
// Mutation
primes[0] = 1
_(primes) // [1, 3, 5, 7]
~~~
## Loops
`* { ... }` after a loop header runs the Block each iteration.
~~~js
// for (init; test; step)
(i: 0; i < 5; i = i + 1) * {
_(i)
}
// while
(!0) * {
// do something forever...
^ // break when done
}
// Controls
>> // continue
^ // break
~~~
## Bridging examples
Closures over private state:
~~~js
makeCounter: {
#v: 0
{
inc: { #v = #v + 1; #v }
value: { #v }
}
}
c: makeCounter()
c.inc() // 1
c.inc() // 2
c.value() // 2
~~~
Tiny program with input and branching:
~~~js
welcome: (name) {
msg: (name && name != "") ? { "Hi, " + name + "!" } : { "Hi!" }
_(msg)
msg
}
welcome("Ada") // "Hi, Ada!"
welcome("") // "Hi!"
~~~
## Notes
- Comments use `//`.
- Strings are `"..."`.
- Blocks return their last expression.
- Private members (`#x`) are visible only inside their Block (and nested Blocks that resolve to it).
---
Hi is still in active development. This page will grow with specs, a reference, and a playground. Contributions and feedback are welcome!
</script>
<script>
document.addEventListener('DOMContentLoaded',()=>{
const $=s=>document.querySelector(s),$$=s=>[...document.querySelectorAll(s)]
const md=window.markdownit({html:true,linkify:true,typographer:true,breaks:false})
const slug=s=>s.toLowerCase().trim().replace(/[^\w\- ]+/g,'').replace(/\s+/g,'-')
const root=$('#suneHtml');root.className='markdown-body max-w-3xl mx-auto';root.innerHTML=md.render($('#md')?.textContent||'')
const heads=$$('#suneHtml h2, #suneHtml h3')
heads.forEach(h=>{
const titleText=(h.childNodes[0]?.nodeValue||h.textContent||'').trim()
h.id=slug(titleText);h.classList.add('anchor')
const a=document.createElement('a');a.href='#'+h.id;a.className='anchor-link';a.innerHTML='#';h.appendChild(a)
})
$$('#suneHtml pre>code').forEach(code=>{
window.hljs&&hljs.highlightElement(code)
const pre=code.parentElement,t=code.textContent||'',box=document.createElement('div'),btn=document.createElement('button'),meta=document.createElement('span')
btn.className='copy-btn';btn.textContent='Copy'
btn.onclick=async()=>{try{await navigator.clipboard.writeText(code.innerText);btn.textContent='Copied';setTimeout(()=>btn.textContent='Copy',1100)}catch{}}
meta.className='char-c';meta.textContent=(t.length>=1e3?`${(t.length/1e3).toFixed(1)}K`:t.length)+' chars'
box.className='code-actions';box.append(meta,btn);pre.appendChild(box)
})
const buildNav=sel=>{
const nav=$(sel);if(!nav)return;nav.innerHTML=''
const frag=document.createDocumentFragment()
heads.forEach(h=>{
const a=document.createElement('a'),title=(h.childNodes[0]?.nodeValue||h.textContent||'').replace(/\s*#\s*$/,'').trim()
a.href='#'+h.id;a.className=(h.tagName==='H3'?'pl-6 ':'')+'block px-2 py-1 rounded-lg hover:bg-gray-100 text-gray-700';a.textContent=title;frag.appendChild(a)
})
nav.appendChild(frag)
const links=[...nav.querySelectorAll('a')]
const io=new IntersectionObserver(es=>{es.forEach(e=>{if(e.isIntersecting){const id='#'+e.target.id;links.forEach(L=>L.classList.toggle('bg-gray-100 font-medium',L.getAttribute('href')===id))}})},{rootMargin:'-50% 0px -40% 0px'})
heads.forEach(h=>io.observe(h))
links.forEach(L=>L.addEventListener('click',()=>{if(window.innerWidth<1024)setLeft(false)}))
}
buildNav('#sideNav');buildNav('#sideNavMobile')
const overlay=$('#overlay'),side=$('#sidebarMobile'),menuBtn=$('#menuBtn'),setLeft=v=>{overlay.classList.toggle('opacity-100',v);overlay.classList.toggle('pointer-events-none',!v);side.classList.toggle('-translate-x-full',!v)}
menuBtn?.addEventListener('click',()=>setLeft(true));overlay?.addEventListener('click',()=>setLeft(false));document.addEventListener('keydown',e=>{if(e.key==='Escape')setLeft(false)})
})
</script>
</body>
</html>